運算符重載形式
重載是c++的一大特性,不僅可以用于一般函數重載,還可以用于運算符重載,對于一些基本資料類型來說運算符可以直接拿來使用,是以運算符重載一般是應用于對象之間,而對象之間的運算符重載主要分為成員運算符重載和友元運算符重載兩種形式。
成員運算符重載:表示在類内定義的這個與運算符相關的函數是屬于類的成員函數。是以他可以直接由對象調用對于雙目運算符他隻需要一個參數(另外一個參數其實就是調用它的對象)
友元運算符重載:以友元函數的形式對對象進行運算符重載,是以對于雙目運算符來說,它需要兩個參數都寫出來。
#include<iostream>
using namespace std;
class A
{
public:
A(int num);
A operator +(int num);
friend A operator+(int,const A&);
void show();
private:
int _num;
};
A::A(int num)
{
_num = num;
}
A A::operator +(int num)
{
cout << "成員運算符重載:" << endl;
A a(this->_num + num);
return a;
}
A operator+(int num, const A& a)
{
cout << "友元運算符重載:" << endl;
//因為是類A的友元函數是以可以通路類A對象的私有成員
A b(num + a._num);
return b;
}
void A::show()
{
cout << this->_num << endl;
}
int main()
{
A a();
a = a + ;
a.show();
a = + a;
a.show();
system("pause");
return ;
}

可以看出:
對象在左邊時調用的是成員運算符重載函數,而對象在右邊時調用的是友元運算符重載函數,因為隻有對象在左邊時對象才可能通路自身的成員函數,對于雙目運算符重載對象在運算符右邊的情況則一定要使用有緣運算符重載才行。
運算符重載種類
一般運算符重載
//加号重載
A operator +(int num);
friend A operator+(int, const A&);
//減号重載
A operator -(int num);
friend A operator-(int, const A&);
//乘号重載
A operator *(int num);
friend A operator*(int, const A&);
//除号重載
A operator /(int num);
friend A operator/(int, const A&);
具體函數實作參照上面加号重載的實作!
邏輯運算符重載
bool operator || (const A&);
bool operator && (const A&);
bool operator ! ();
bool A::operator&&(const A& a)
{
bool ret=false;
if(a._num&&this->_num)
ret=true;
return ret;
}
bool A::operator||(const A& a)
{
bool ret=false;
if(a._num||this->_num)
ret=true;
return ret;
}
bool A::operator!()
{
bool ret=false;
if(!this->_num)
ret=true;
return ret;
}
這裡的邏輯運算符的兩個運算對象都是同一個類的對象是以隻使用成員運算符重載即可,但如果兩個運算對象是不同的類型則還需要使用友元運算符重載保證即使兩個運算對象調換左右位置仍能正常達到運算符重載的效果。
流運算符重載
流運算符包括輸入流和輸出流。
流運算符重載的兩個運算對象一個是輸入緩沖區/輸出緩沖區,另一個是要輸入/輸出的對象。而類的對象在流運算符的右邊,不能通過通路成員函數的形式調用運算符重載函數,是以隻能使用友元運算符重載的形式。
friend ostream& operator << (ostream&, A&);
friend istream& operator >> (istream&, A&);
ostream& operator << (ostream& output, A& a)
{
output<<a._num;
return output;
}
istream& operator >> (istream& iutput, A& a)
{
input >> a._num;
return input;
}
指派運算符重載
A& operator = (const A&);
A& operator += (const A&);
A& operator -= (const A&);
A& operator *= (const A&);
A& operator /= (const A&);
A& A::operator += (const const A& a)
{
this->_num=this->_num+a._num;
return *this;
}
因為是指派運算符,是以在對對象指派後還要傳回對象的引用,這也是它與直接的四則運算符一個不同的地方(+,=,*,/隻是傳回一個臨時對象!)。
關系運算符
關系運算的目的是為了判斷倆個運算對象是不是滿足某種關系,滿足傳回true,不滿足傳回false,是以關系運算符重載的傳回值都為bool類型。
bool operator > (const A& );
bool operator < (const A& );
bool operator == (const A& );
bool operator >= (const A& );
bool operator <= (const A& );
bool A::operator >= (const A& a)
{ bool ret=false;
if(this->_num>a._num)
ret=true;
return ret;
}
//其它的類似
四則運算符重載和拷貝構造函數的配合
四則運算符重載函數傳回的值是一個臨時對象,在将這個傳回值指派給左值時根據左值的不同分為兩種情況:
對象3=對象1+對象2;
這時傳回值指派給左值時會調用轉換構造函數拿着這個傳回值生成一個臨時對象再将這個對象指派給左值。
類名 對象名=對象1+對象2
這時傳回值指派給左值時,會直接調用拷貝構造函數,根據這個傳回值生成新對象。
以上不論哪種情況都會調用拷貝構造函數,是以如果類内含有指針,對四則運算符進行重載時一定要對拷貝構造函數重載使其從淺拷貝變為深拷貝!
class A
{
public:
A();
A(char *);
~A();
A operator +(const A&);
A(const A&);
void show();
private:
char* _data;
int _len;
};
A::A()
{
_len = ;
_data = nullptr;
}
A::A(char * str)
{
_len = strlen(str) + sizeof(char);
_data = new char[_len];
strcpy(_data, str);
}
A::~A()
{
if(_data)
delete[] _data;
}
A A::operator +(const A& a)
{
char ch[];
strcpy(ch, _data);
strcat(ch, a._data);
A temp(ch);
return temp;
}
//深拷貝,為新生成對象内部指針成員變量重新配置設定空間。
A::A(const A& a)
{
this->_len = a._len;
_data = new char[_len];
strcpy(this->_data, a._data);
}
void A::show()
{
cout << this->_data << endl;
}
int main()
{
A a1("12");
A a2("34");
A a3= a1 + a2;
a1.show();
a2.show();
a3.show();
system("pause");
return ;
}
運作結果:
這裡要注意的是:第一種情況中不僅要對拷貝構造函數重載還要對’=‘進行重載為對象的指針變量重新配置設定控件,不然在最後一步對象之間指派時仍然會出錯!