操作符重載 正規寫法(鏈式編程+友元函數應用場景)
- 正規寫法
- 值得注意的點
- 總結
閱讀之前注意:
本文閱讀建議用時:30min
本文閱讀結構如下表:
項目 | 下屬項目 | 測試用例數量 |
---|---|---|
正規寫法 | 無 | 1 |
值得注意的點 | 無 | 0 |
總結 | 無 | 0 |
正規寫法
從上一篇博客我們知道了怎麼重載C++中的輸出操作符“<<”,那些代碼雖然很好的體現了技術的演變過程,但卻不夠嚴謹和規範。從嚴謹性來說,缺點在於無法實現鏈式編程,即無法使用“cout<<自定義對象1<<自定義對象2<<endl
”這樣的語句;從規範性來說,變量設置爲public並不合理(應該設置爲私有屬性private以保護內部數據)。
因此,現在我們按照正規寫法來,首先,像“+”號、“++”號等的重載實現,可以在類的內部實現,就應該在類的內部實現,而不應該濫用全局函數,那什麼時候採用全局函數呢?自然就是那些無法在類的內部實現重載的操作符了,輸出操作符”<<”即是很好的例子,因爲我們無法去修改cout這個類,所以採用全局函數來重載”<<”;其次,當把類的內部變量設置爲private時,產生了一個問題,全局函數無法訪問私有變量,解決方法就是友元函數聲明。
以下是完整演示代碼1:
#include"iostream"
using namespace std;
class A
{
public:
A(int a = 0, int b = 0)
{
this->a = a;
this->b = b;
}
void print()
{
cout << "a" << this->a << " b" << this->b << endl;
}
A operator+(A &A2)
{
A tmp;
tmp.a = this->a + A2.a;//注意:私有是針對類而言的
tmp.b = this->b + A2.b;
return tmp;
}
A &operator++()//前置++
{
this->a++;
this->b++;
return *this;
}
A operator++(int)//後置++
{
A tmp = *this;//調用拷貝構造函數
this->a++;
this->b++;
return tmp;//返回臨時對象,類做返回值會調用拷貝構造函數
}
//friend void operator<<(ostream &out,A &a1);//非鏈式編程
friend ostream& operator<<(ostream &out, A &a1);//友元函數聲明+鏈式編程
private:
int a;
int b;
};
ostream &operator<<(ostream &out,A &a1)//用全局函數實現操作符重載
{
out << "a" << a1.a << " b" << a1.b << endl;
return out;
}
void main1()//測試場景1
{
A a1(1, 2), a2(3, 4);
++a1;
a1.print();
cout << a1;
cout << a1++;
cout << ++a1;
A a3 = a1 + a2;
cout << a3;
//沒有辦法在cout類裏面添加函數operator<<,只能通過全局函數實現
//cout.operator<<(a3);
system("pause");
}
void main()//測試場景
{
A a1(1, 2), a2(3, 4);
cout << a1 << a2 << endl;//鏈式編程
//函數返回值當左值的情況,需要返回一個對象的引用
//operator<<(cout, a1);
system("pause");
}
值得注意的點
以上代碼爲了實現鏈式編程,即函數返回值當左值的情況,需要返回一個對象的引用。
總結
本篇博客的核心是:操作符重載如果無法在類的內部實現,則應通過友元函數聲明,用全局函數實現重載。
- 代碼基於王保明先生的講課內容. ↩