您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“C++編程語言中賦值運算符重載函數(shù)怎么使用”,內(nèi)容詳細,步驟清晰,細節(jié)處理妥當,希望這篇“C++編程語言中賦值運算符重載函數(shù)怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。
首先介紹為什么要對賦值運算符“=”進行重載。某些情況下,當我們編寫一個類的時候,并不需要為該類重載“=”運算符,因為編譯系統(tǒng)為每個類提供了默認的賦值運算符“=”,使用這個默認的賦值運算符操作類對象時,該運算符會把這個類的所有數(shù)據(jù)成員都進行一次賦值操作。例如有如下類:
class A { public: int a; int b; int c; };
對這個類的對象進行賦值時,使用默認的賦值運算符是沒有問題的。
示例代碼內(nèi)容如下:
#include <iostream> using namespace std; class ClassA { public: int a; int b; int c; }; int main() { ClassA obj1; obj1.a = 1; obj1.b = 2; obj1.c = 3; ClassA obj2; obj2 = obj1; cout << "obj2.a is: " << obj2.a << endl; return 0; }
編譯并執(zhí)行上述代碼,結(jié)果如下:
通過上述結(jié)果能夠知道:通過使用系統(tǒng)默認的賦值運算符“=”,可以讓對象 obj2 中的所有數(shù)據(jù)成員的值與對象 obj1 相同。這種情況下,編譯系統(tǒng)提供的默認賦值運算符可以正常使用。
但是,在下面的示例中,使用編譯系統(tǒng)提供的默認賦值運算符,就會出現(xiàn)問題了。
示例代碼內(nèi)容如下:
#include <iostream> #include <string.h> using namespace std; class ClassA { public: ClassA() { } ClassA(const char* pszInputStr) { pszTestStr = new char[strlen(pszInputStr) + 1]; strncpy(pszTestStr, pszInputStr, strlen(pszInputStr) + 1); } virtual ~ClassA() { delete pszTestStr; } public: char* pszTestStr; }; int main() { ClassA obj1("liitdar"); ClassA obj2; obj2 = obj1; cout << "obj2.pszTestStr is: " << obj2.pszTestStr << endl; cout << "addr(obj1.pszTestStr) is: " << &obj1.pszTestStr << endl; cout << "addr(obj2.pszTestStr) is: " << &obj2.pszTestStr << endl; return 0; }
編譯并運行上述代碼,結(jié)果如下:
上述錯誤信息表明:當對象 obj1 和 obj2 進行析構(gòu)時,由于重復(fù)釋放了同一塊內(nèi)存空間,導(dǎo)致程序崩潰報錯。在這種情況下,就需要我們重載賦值運算符“=”了。
我們修改一下前面出錯的示例代碼,編寫一個包含賦值運算符重載函數(shù)的類,修改后的代碼內(nèi)容如下:
#include <iostream> #include <string.h> using namespace std; class ClassA { public: ClassA() { } ClassA(const char* pszInputStr) { pszTestStr = new char[strlen(pszInputStr) + 1]; strncpy(pszTestStr, pszInputStr, strlen(pszInputStr) + 1); } virtual ~ClassA() { delete pszTestStr; } // 賦值運算符重載函數(shù) ClassA& operator=(const ClassA& cls) { // 避免自賦值 if (this != &cls) { // 避免內(nèi)存泄露 if (pszTestStr != NULL) { delete pszTestStr; pszTestStr = NULL; } pszTestStr = new char[strlen(cls.pszTestStr) + 1]; strncpy(pszTestStr, cls.pszTestStr, strlen(cls.pszTestStr) + 1); } return *this; } public: char* pszTestStr; }; int main() { ClassA obj1("liitdar"); ClassA obj2; obj2 = obj1; cout << "obj2.pszTestStr is: " << obj2.pszTestStr << endl; cout << "addr(obj1.pszTestStr) is: " << &obj1.pszTestStr << endl; cout << "addr(obj2.pszTestStr) is: " << &obj2.pszTestStr << endl; return 0; }
編譯并運行上述代碼,結(jié)果如下:
通過上述結(jié)果能夠看到,利用賦值運算符重載函數(shù),解決了對象賦值時,析構(gòu)函數(shù)多次釋放同一塊內(nèi)存空間的問題。
對于上述代碼,有以下幾點需要說明:
當為一個類的對象賦值(可以用本類對象為其賦值,也可以用其它類型的值為其賦值)時,該對象(如本例的 obj2)會調(diào)用該類的賦值運算符重載函數(shù),進行具體的賦值操作。如上述代碼中的“obj2 = obj1;”語句,用 obj1 為 obj2 賦值,則會由 obj2 調(diào)用 ClassA 類的賦值運算符重載函數(shù);
下方語句和語句“ClassA obj2 = obj1;”在調(diào)用函數(shù)上是有區(qū)別的:前者第一句是對象 obj2 的聲明及定義,調(diào)用類 ClassA 的無參構(gòu)造函數(shù),所以“obj2 = obj1;”一句是在對象 obj2 已經(jīng)存在的情況下,用 obj1 來為 obj2 賦值,調(diào)用的是賦值運算符重載函數(shù);而后者,是用 obj1 來初始化 obj2,調(diào)用的是拷貝構(gòu)造函數(shù)??截悩?gòu)造函數(shù)的語句樣式為“ClassA(const ClassA& cls)”,關(guān)于拷貝構(gòu)造函數(shù)的詳細內(nèi)容,請參考相關(guān)內(nèi)容,此處不展開介紹;
ClassA obj2; obj2 = obj1;
當程序沒有顯式地提供一個以“本類或本類的引用”為參數(shù)的賦值運算符重載函數(shù)時,編譯器會自動生成一個默認的賦值運算符重載函數(shù)(即默認賦值運算符)。
示例代碼內(nèi)容如下:
#include<iostream> #include<string> using namespace std; class Data { private: int data; public: // 構(gòu)造函數(shù) Data() { }; // 構(gòu)造函數(shù) Data(int _data):data(_data) { cout << "This is constructor" << endl; } // 賦值運算符重載函數(shù) Data& operator=(const int _data) { cout << "This is operator=(int _data)" << endl; data = _data; return *this; } }; int main() { // 調(diào)用構(gòu)造函數(shù) Data data1(1); Data data2, data3; // 調(diào)用賦值運算符重載函數(shù) data2 = 1; // 調(diào)用默認的賦值運算符重載函數(shù) data3 = data2; return 0; }
編譯并執(zhí)行上述代碼,結(jié)果如下:
上述結(jié)果表明:“data2 = 1;”語句調(diào)用了我們提供的以 int 型參數(shù)(而非本類或本類的引用)為形參的賦值運算符重載函數(shù);而“data3 = data2;”的成功執(zhí)行,說明該語句調(diào)用了編譯器提供的默認的賦值運算符重載函數(shù)。
如果將上述代碼中賦值運算符重載函數(shù)去掉,重新編譯執(zhí)行,結(jié)果如下:
上述結(jié)果說明,當用一個非類 A 的值(如上面的 int 類型值)為類 A 的對象賦值時:
如果檢測到構(gòu)造函數(shù)和賦值運算符重載函數(shù)同時存在,則會優(yōu)先調(diào)用賦值運算符重載函數(shù);
如果只檢測到構(gòu)造函數(shù),就會調(diào)用構(gòu)造函數(shù)。
讀到這里,這篇“C++編程語言中賦值運算符重載函數(shù)怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。