一、運算符重載
運算符重載允許把標准運算符(如+、-、*、/、<、>等)應用於自定義數據類型的對象
直觀自然,可以提高程序的可讀性
體現了C++的可擴充性
運算符重載僅僅只是語法上的方便,它是另一種函數調用的方式
運算符重載,本質上是函數重載
不要濫用重載、因為它只是語法上的方便,所以只有在涉及的代碼更容易寫、尤其是更易讀時才有必要重載
二、成員函數重載
成員函數原型的格式:
函數類型 operator 運算符(參數表);
成員函數定義的格式:
函數類型 類名::operator 運算符(參數表)
{
函數體;
}
三、非成員函數重載
友元函數原型的格式:
friend 函數類型 operator 運算符(參數表);
友元函數定義的格式:
函數類型 類名::operator 運算符(參數表)
{
函數體;
}
四、運算符重載的原則
運算符重載不允許發明新的運算符。
不能改變運算符操作對象的個數。
運算符被重載后,其優先級和結合性不會改變。
不能重載的運算符:
作用域解析運算符 ::
條件運算符 ? :
直接成員訪問運算符 .
類成員指針引用的運算符 .*
sizeof運算符 sizeof
注:.*是C++的類成員函數指針調用運算符,是用來調用一個類函數指針的。
舉例:
假設有一個ClassA類擁有一個成員函數void ClassA::func(int i),則可以這么用:
void (ClassA::*fp)(int i) // 定義一個類函數指針。
ClassA obj;
fp = &ClassA::func; // 給這個類函數指針賦值
(obj.*fp)(5); // 這么用,相當於調用obj.func(5);
一般情況下,單目運算符最好重載為類的成員函數;雙目運算符則最好重載為類的友元函數。
以下一些雙目運算符不能重載為類的友元函數:=、()、[]、->。
類型轉換運算符只能以成員函數方式重載(見這里)
流運算符只能以友元的方式重載(見這里)
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#ifndef _COMPLEX_H_ #define _COMPLEX_H_ class Complex { public: Complex(int real, int imag); Complex(void); ~Complex(void); Complex &Add(const Complex &other); void Display() const; Complex operator+(const Complex &other); friend Complex operator+(const Complex &c1, const Complex &c2); private: int real_; int imag_; }; #endif |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include "Complex.h" #include<iostream> using namespace std; Complex::Complex(int real, int imag): imag_(imag), real_(real) { } Complex::Complex(void) { } Complex::~Complex(void) { } Complex &Complex::Add(const Complex &other) { real_ += other.real_; imag_ += other.imag_; return *this; } void Complex::Display() const { cout << real_ << "+" << imag_ << "i" << endl; } Complex Complex::operator+(const Complex &other) { int r = real_ + other.real_; int i = imag_ + other.imag_; return Complex(r, i); } Complex operator+(const Complex &c1, const Complex &c2) { int r = c1.real_ + c2.real_; int i = c1.imag_ + c2.imag_; return Complex(r, i); } |
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include "Complex.h" int main(void) { Complex c1(3, 5); Complex c2(4, 6); c1.Add(c2); c1.Display(); Complex c3 = c1 + c2; // 等價於c1.opertor+(c2); 或 operator+(c1, c2); c3.Display(); return 0; } |
我們實現了Add成員函數,但c1.Add(c2); 改變的是c1 本身;如果我們想實現加號表達式,c3 = c1 + c2; 那么可以實現operator+ 運算符重載,可以是成員函數形式,也可以是友元形式,如果兩者共存的話成員函數優先。
參考:
C++ primer 第四版
Effective C++ 3rd
C++編程規范