C++運算子過載(注意點),友元(使用和優缺點)
阿新 • • 發佈:2019-01-11
運算子過載例項程式碼
class A{
public:
int a,b;
A(int _a=0,int _b=0):a(_a),b(_b){}
A operator+(A & tmpa){
A t;
t.a = this->a + tmpa.a;
t.b = this->b + tmpa.b;
return t;
}
friend ostream& operator <<(ostream& os,A &tmpa){
os << "(" << tmpa.a << "," << tmpa.b << ")";
return os;
}
};
int main()
{
freopen("in.txt", "r", stdin);
A a1(1,1);
A a2(2,3);
A a3 = a1 + a2;
A a4 = a1.operator+(a2);
cout << a1 << endl;
return 0;
}
過載運算子可以使用成員函式或非成員函式兩種方法
注意只能使用其中的一種方法
以運算子+為例:
作為成員函式
A operator+(A & tmpa){
A t;
t.a = this->a + tmpa.a;
t.b = this->b + tmpa.b;
return t;
}
- 需要有兩個運算子,因為是成員函式,所以有一個this指標隱含的傳過去,只需要一個引數就行了
在使用的時候,有如下的兩種使用方式,operator+ 類似於一個成員函式方法名,直接呼叫
A a3 = a1 + a2;
A a4 = a1.operator+(a2);
作為非成員函式
operator+ 需要指定兩個運算元,宣告為友元函式
// 宣告在函式內部
friend A operator+(const A &t1, const A &t2);
// 具體實現
A operator+(const A &t1, const A &t2)
{
A t;
t.a = t1.a + t2.a;
t.b = t1.a + t2.b;
return t;
}
在使用的時候
A a3 = a1 + a2; // 可用
A a4 = a1.operator+(a2); // 錯誤,應為opetor+不是類成員方法
友元
1 為什麼引入友元函式
實現類之間的資料共享,減少系統開銷,提高效率;使得其它的類成員函式能直接訪問該類的私有變數
缺點: 友元函式破壞了封裝機制,儘量不要使用
2 什麼時候使用友元函式
- 運算子過載的某些場合需要友元
- 兩個類共享資料時
3 友元函式沒有this指標,是類外的函式
友元函式的宣告可以在類的私有段或公有段,且沒有區別
可以直接呼叫友元函式,不需要通過物件或指標
友元函式的引數:
1 訪問非static成員時,需要物件作引數
2 訪問static成員時,不需要物件作引數
3 引數是全域性物件時,不需要物件作引數
運算子過載注意點
- 過載的運算子(有些是例外情況)不必是成員函式(可以用友元函式來實現),但是必須至少有一個運算元是使用者自定義的型別(物件型別本身)。
class Myclass{
public:
double f;
Myclass(double _f = 0.0):f(_f){}
public:
friend Myclass operator*(Myclass m, double d); // 1
friend Myclass operator*(Myclass m, Myclass m2); // 2
friend Myclass operator*(double d, Myclass m); // 3
//friend Myclass operator*(double d, double d2);
};
Myclass operator*(Myclass m, double d)
{
Myclass m2;
m2.f = m.f * d;
return m2;
}
Myclass operator*(double d, Myclass m)
{
Myclass m2;
m2.f = m.f * d;
return m2;
}
int main()
{
Myclass m1(2.1);
Myclass m2 = m1 * 3; // 對應呼叫1, 否則出現無法解析符號相關報錯
Myclass m3 = 4 * m1; // 對應呼叫3
return 0;
}
- 使用運算子時不能違反運算子原來的句法規則。例如,不能將取模運算子(%)過載成只使用一個運算元
如下,因為成員函式預設有一個this引數,乘法(*)運算子是兩個運算元,所以只有一個引數,不能有多的引數
過載的運算子 ,不會改變優先順序
不能建立新的的運算子來過載,例如不能定義 operator**()函式來表示求冪
有些運算子不能過載
- 運算子過載可用成員函式,或友元函式,但是有些運算子的過載只能用 成員函式