C++赋值运算符重载【C++赋值运算符重载】
- 賦值運算符重載
- 說明
- 語法
- 特性
- 自實現存在的問題
- 重析構
- 內存泄漏
- 自賦值
- 解決
- 小結
賦值運算符重載
說明
賦值運算符重載是用一個已經存在的對象,給另一個已經存在的對象賦值,兩個對象均已創建結束后,發生賦值行為。
語法
格式固定:
類名 { 類名 & operator=(const 類名 & 源對象) {//拷貝體return *this; } } class A { A & operator=(const A & another) { //函數體 return *this; } };特性
代碼演示:
#include <iostream> using namespace std;struct Data { public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d){}void dis(){cout << " year " << year << " month " << month << " day " << day << endl;} private:int year;int month;int day; };int main() {Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0; }運行結果:
可以看到并沒有自己寫賦值運算符重載,但是確實賦值成功了,并且正確賦值。
進行說明:
系統默認提供的賦值運算符重載。也是一種淺賦值行為。
理解:
拷貝構造器和賦值運算符重載的區別,拷貝構造器是原來不存在直接進行構造一份,賦值運算符重載是本來就有兩份,然后拿第一份的將第二份覆蓋。
如果對象中不存在堆內存空間,此時系統默認提供的賦值運算符重載可以滿足需求。如果對象中含有堆上的內存空間則需要自實現完成深拷貝。
格式語法固定。
一旦自實現,系統默認提供的賦值運算符重載將不存在。
如果自實現了但是里面沒有內容,那么就不能實現賦值運算符重載:
#include <iostream> using namespace std;struct Data { public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d), space(new char[1024]){}Data & operator = (const Data& another){}void dis(){cout << " year " << year << " month " << month << " day " << day << endl;} private:int year;int month;int day;char* space; };int main() {Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0; }運行結果為:
可以看到賦值運算符沒有重載成功。
自實現運算符重載:
#include <iostream> using namespace std;struct Data { public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d), space(new char[1024]){}Data & operator = (const Data& another){this->year = another.year;this->month = another.month;this->day = another.day;return *this;}void dis(){cout << " year " << year << " month " << month << " day " << day << endl;} private:int year;int month;int day;char* space; };int main() {Data d(2018, 8, 8); d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0; }運行結果:
上面實例中實現的賦值運算符重載和系統默認提供的賦值運算符重載實現的結果是一樣的。
為什么在運算符重里面加入了return * this:
給出main函數中的代碼,其他代碼不變:
理解:d賦值給d2,整個表達式返回了d2,然后d2作為參數進行傳遞,將d2賦值給d3,整個表達式又返回d3。
自實現存在的問題
重析構
在釋放內存的時候就會出現重析構問題。
內存泄漏
解決:先把自己之前的內存進行釋放,然后進行深拷貝。
自賦值
自賦值意思就是說當出現自己賦值給自己的時候,那么原來的內存空間被釋放了,但是原來的內存空間里面還是自己本身,如果釋放之后就無法進行賦值運算符重載,所以我們在自實現的是時候就要解決這個問題。
解決
代碼實現:
#define _CRT_SECURE_NO_WARNINGS #include <string.h> #include <iostream> using namespace std;struct Data { public:Data(int y = 2016, int m = 6, int d = 6):year(y), month(m), day(d), space(new char[1024]){}Data& operator = (const Data& another)//賦值運算符重載{if (this == &another) //解決自賦值的問題return *this; //實現鏈式表達else{delete[]this->space; //解決內存泄漏的問題space = new char[strlen(another.space) + 1];strcpy(space, another.space);}year = another.year;month = another.month;day = another.day;return *this;}~Data() //析構器{cout << "~~~~~~~~" << this << endl; //指向當前對象的指針delete[]space;}void dis(){cout << " year " << year << " month "<< month << " day " << day << endl;} private:int year;int month;int day;char* space; };int main() {Data d(2018, 8, 8);d.dis();Data d2(2019, 9, 9);d2 = d;d2.dis();return 0; }上面自實現代碼就解決了這三個問題。
運行結果:
接下來進行說明在:
Data & operator = (const Data & another)
進行傳遞的時候參數使用 const 的作用就是 another 里面的內容肯定不會修改。
那么 Data & operator = (const Data & another)
最前面沒有引用,所以可以返回this指針的內容,如果給最前面也加上const。
const Data & operator = (const Data & another)
我們可以看到如果在返回引用的時候沒有使用const ,返回之后可以被賦值。如果不想被賦值就在返回類型前面加上const。
例如:(d3 = d2) = d; 如果前面有const那么表達式不可以被賦值。
小結
總結
以上是生活随笔為你收集整理的C++赋值运算符重载【C++赋值运算符重载】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++模板:类模板和类模板的友元【C++
- 下一篇: 派生类的赋值运算符重载【C++继承】