問題描述:對于自定義型別來說,我下方代碼中的賦值運算子多載時函式回傳值和引數型別為什么一定要是參考型別呢(若不是參考型別該程式會出錯,錯誤提示在代碼下方)?注釋部分是我自己的理解,請各位大神幫忙看看有什么錯誤幫忙指正一下,先謝謝各位了。
#include<iostream>
using namespace std;
//賦值運算子多載
class Person
{
public:
Person(int age)
{
m_Age = new int(age);
}
//引數必須是參考型別,若是值型別,在函式結束時會執行解構式把指標(傳入的p.m_Age)指向的記憶體空間釋放掉.
Person& operator=(Person &p)
{
//如果有未釋放的堆區空間,先釋放
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
m_Age = new int(*p.m_Age);
return *this;
}
~Person()
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
}
int *m_Age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);
p3 = p2 = p1;
//對于自定義資料型別,等號運算子多載回傳值必須是參考型別
//如上方代碼相當于p3.operator=(p2.operator=(p1));,其中引數傳遞程序
即 Person &p = p2.operator=(p1);,如果operator= 函式回傳的是值型別
//則會先在記憶體中創建一個臨時物件temp用于接收傳遞來的物件副本,然后用這個臨時物件為參考p初始化
//而臨時物件生命周期很短,僅在當前陳述句結束后就釋放其記憶體空間,而后再通過p訪問臨時變數的記憶體空間則是非法操作。
cout << "p1的年齡為:" << *p1.m_Age << endl;
cout << "p2的年齡為:" << *p2.m_Age << endl;
cout << "p3的年齡為:" << *p3.m_Age << endl;
}
int main(void)
{
test01();
system("pause");
return 0;
}
錯誤提示:
case1:當回傳值不是參考型別時提示:
錯誤 C2679 二進制“=”: 沒有找到接受“Person”型別的右運算元的運算子(或沒有可接受的轉換)
case2 :當引數不是參考型別時提示:

uj5u.com熱心網友回復:
回傳值是可以的,你出錯是因為你沒有判斷自我賦值也就是T a;
a=a;//這種形式
當出現這種形式的時候
你的operator=
先把a的age洗掉,在賦值給a,所以出錯。
回傳值的情況,它的缺點是多一次復制,效率不高
uj5u.com熱心網友回復:
還有你的類沒有自定義拷貝建構式。Person &p = p2.operator=(p1);
默認情況下沒有拷貝建構式,編譯器會自動提供,它的實作就是把目標和原物件進行二進制的賦值。
這句話執行完畢p 和 p2 的age指向了同一個記憶體區域,所以當一個物件釋放完畢后,下一個物件再次釋放會出錯。
uj5u.com熱心網友回復:
我添加了對自我賦值的判斷之后,還是提示:
錯誤 C2679 二進制“=”: 沒有找到接受“Person”型別的右運算元的運算子(或沒有可接受的轉換)
#include<iostream>
using namespace std;
//賦值運算子多載
class Person
{
public:
Person(int age)
{
m_Age = new int(age);
}
//多載賦值運算子,用深拷貝解決淺拷貝的問題
//在堆區開辟新的空間將被拷貝物件中指標成員所指向的值拷貝過來
//引數必須是參考型別,若是值型別,在函式結束時會執行解構式把指標(傳入的p.m_Age)指向的記憶體空間釋放掉.
Person operator=(Person &p)
{
//判斷是否自我賦值
if(&p == this)
{
return *this;
}
//如果有未釋放的堆區空間,先釋放
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
//深拷貝
m_Age = new int(*p.m_Age);
return *this;
}
~Person()
{
if (m_Age != NULL)
{
delete m_Age;
m_Age = NULL;
}
}
int *m_Age;
};
void test01()
{
Person p1(18);
Person p2(20);
Person p3(30);
p3 = p2 = p1;
//如上方代碼相當于p3.operator=(p2.operator=(p1));,其中引數傳遞程序即 Person &p = p2.operator=(p1);,如果operator= 函式回傳的是值
//則會先在記憶體中創建一個臨時物件temp用于接收傳遞來的物件副本,然后用這個臨時物件為參考p初始化
//而臨時物件宣告周期很短,僅在當前陳述句結束后就釋放其記憶體空間,而后再通過p訪問臨時變數的記憶體空間則是非法操作。
cout << "p1的年齡為:" << *p1.m_Age << endl;
cout << "p2的年齡為:" << *p2.m_Age << endl;
cout << "p3的年齡為:" << *p3.m_Age << endl;
}
int main(void)
{
test01();
system("pause");
return 0;
}
uj5u.com熱心網友回復:
Person operator=(const Person &p)轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/264607.html
標籤:新手樂園
上一篇:vc++
