C++學習筆記(二) 運算子過載
操作符過載
定義:讓加減乘除,不侷限於整型數的操作,也可以實現類的相加…
例項:
加法過載
class Point
{
private:
int x;
int y;
...
};
Point operator+(Point &p1, Point &p2)
{
cout<<"this is a operator +"<<endl;
Point n;
n.x = p1.x + p2.x;
n.y = p1.y + p2.y;
return n;
}
通過過載,就可以實現類的相加了
有趣的現象
b = a++;
(先執行 b = a,再執行 a = a+1)
b = ++a;
(先執行 a = a + 1,再執行 b = a)
自加的過載實現
class Point
{
private:
int x;
int y;
...
};
/* Point p(1,2); ++p */
Point &operator++(Point &p)
{
cout<<"++p"<<endl;
p.x += 1;
p.y += 1;
return p;
}
/* Point p(1,2); p++ */
Point operator++(Point &p, int a)
{
cout<<"p++"<<endl;
Point n;
n = p
p.x += 1;
p.y += 1;
return n;
}
++p和p++進行過載時函式名一模一樣,通過什麼來區分?
答:通過傳入不同引數來區分
在++p的過載函式和p++的過載函式中的返回值為什麼不一樣?為什麼++p的返回值要以引用的形式出現?
首先在Point類的建構函式和解構函式裡面加入列印資訊
class Point
{
private:
int x;
int y;
public:
Point()
{
cout<<"Point()"<<endl;
}
Point(int x, int y) : x(x), y(y)
{
cout<<"Point(int x, int y)"<<endl;
printInfo();
}
/* 拷貝建構函式 */
Point(const Point &p)
{
cout<<"Point(const Point &p)"<<endl;
x = p.x;
y = p.y;
}
~Point()
{
cout<<"~Point()"<<endl;
}
...
};
接下來看一下主程式
int main()
{
Point p(1, 2);
cout<<"begin"<<endl;
p++;
cout<<"萬能的分隔符"<<endl;
++p;
cout<<"end"<<endl;
return 0;
}
程式執行結果如下
Point(int x, int y)
(1, 2)
begin
p++
Point()
Point(const Point&p)
~Point()
~Point()
萬能的分隔符
++p
end
~Point()
下面對執行結果進行逐行分析
1:執行Point p(1, 2)這句時,進入建構函式
2:建構函式Point(int x, int y)裡面的列印資訊
3:main函式裡面的列印資訊
4:執行p++時,程式跳轉到函式operator++(p++)裡面的列印資訊
5: operator++(p++) 裡面的Point n,新建了一個物件,產生的建構函式裡執行的列印資訊
6: operator++(p++) 函式裡面物件p的生成時呼叫了拷貝建構函式(拷貝建構函式不在本次討論過程中),從而列印資訊
7,8:依次銷燬物件p和物件n,呼叫了解構函式
9:main函式裡萬能的分隔符
10:執行++p時,程式跳轉到函式operator++(++p) 裡面的列印資訊
11:main函式裡面的列印資訊
12:銷燬main函式裡面一開始建立的物件p時呼叫解構函式產生的列印資訊
根據以上的分析,或許你已經得到了答案
為什麼要用引用返回?
當你函式需要返回值時,上述的p++ 是進行值返回,需要依靠拷貝建構函式建立物件,然後返回物件的值,最後把物件銷燬。由此可見,在它建立物件的那個過程,白白浪費了資源。上述的++p是進行引用返回,省去了建立新物件的過程,直接通過引用傳入物件的地址,從而不會浪費空間資源。
既然引用返回那麼好用,為什麼p++不使用引用返回?
我們繼續對如下程式碼分析
Point operator++(Point &p, int a)
{
cout<<"p++"<<endl;
Point n;
n = p;
p.x += 1;
p.y += 1;
return n;
}
這裡的Point n申請的變數儲存在棧空間中,當這個函式結束後就會釋放記憶體。如果這個時候你想使用引用返回,相當於它將這片地址返回給呼叫它的程式。然而,在函式結束時,這片地址所指向的記憶體已經釋放掉了,如果你採用引用返回,就會出現異常。所以,在這裡使用引用返回是不妥的。
相關文章
- C++ 運算子過載C++
- C++——運算子過載C++
- C++運算子過載C++
- Java學習筆記--運算子Java筆記
- C++運算子過載詳解C++
- C++中運算子的過載C++
- C++ 過載運算子和過載函式C++函式
- Flutter學習筆記(5)--Dart運算子Flutter筆記Dart
- Rxjs TakeUntil 運算子的學習筆記JS筆記
- C++過載的奧義之運算子過載C++
- C語言學習筆記--C運算子C語言筆記
- 課堂筆記 - C++ 位運算子筆記C++
- 【python隨筆】之【運算子過載】Python
- 過載運算子
- 運算子過載
- C++學習筆記(二)——函式C++筆記函式
- C++運算子過載的一些困惑C++
- 教你快速理解C++中的運算子過載C++
- Solidity語言學習筆記————14、左值運算子Solid筆記
- Solidity語言學習筆記————9、左值運算子Solid筆記
- Python3學習筆記3,變數、運算子Python筆記變數
- shell指令碼程式設計學習筆記-運算子指令碼程式設計筆記
- 開心檔之C++ 過載運算子和過載函式C++函式
- [Lang] 運算子過載
- Python 運算子過載Python
- 【筆記】Python基礎(二)運算子介紹筆記Python
- 自學PHP筆記(五) PHP運算子PHP筆記
- C++之【操作符】彙總 &【不能被過載的運算子】小記C++
- python之運算子過載Python
- Solidity語言學習筆記————8、運算子優先順序Solid筆記
- Django 筆記 - 特殊運算子Django筆記
- c++ 運算子過載、執行緒安全實現單例C++執行緒單例
- C++ primer Plus學習筆記(第二章)C++筆記
- C#學習筆記---異常捕獲和變數運算子C#筆記變數
- Javascript實現運算子過載JavaScript
- 指標運算子過載(* 和 ->)指標
- Shell學習【運算子】
- C++學習筆記——003C++筆記