1、等號操作符重載,實現深拷貝
//等號運算符重載 // obj3=obj1;//原始的是淺拷貝,現在要重載為深拷貝 Name& operator=(Name &obj1) { //1、先釋放舊的內存 if (this->m_p != nullptr) { delete[] m_p; m_len = 0; } //2、根據 obj1 分配內存大小 this->m_len = obj1.m_len; this->m_p = new char[m_len + 1];
//3、把obj1賦值給obj3 strcpy(m_p, obj1.m_p); return *this;//返回引用,實現鏈式編程 }
2、賦值運算符重載
由於動態申請了堆空間,因此必須重載復制構造函數和賦值運算符:
(1)復制構造函數在創建對象時調用,此時對象還不存在,只需申請空間,不需釋放原有的;
(2)賦值運算符在對象已經存在的情況下調用,需要先釋放原有對象占用的空間,然后申請新的空間;由於原有空間大小不一定滿足現有需求,所以要先釋放后申請。
問題:
(1)刪除賦值運算符的重載,程序是否正常,為什么?
答:程序可以正常運行,但結束時會出現內存錯誤,因為 name 所指向的內存被釋放了 2 次。 由於自動調用了默認的 等號運算符 ,出現兩個對象公用一個內存空間。
class student { public: student(int i = 0, char *c = NULL, float s = 0); student(student& s); student& operator=(student& s); ~student() { delete []name; } void printstu() { cout << "numner: " << id << " name: " << name << " score: "<<score << endl; } private: int id; char* name; float score; }; student::student(int i, char* c, float s) { id = i; score = s; if (c == NULL) { name = nullptr; } else { name = new char[strlen(c) + 1]; strcpy_s(name, strlen(c) + 1, c); } } // 復制構造函數 student::student(student& s) { id = s.id; score = s.score; name= new char[strlen(s.name) + 1]; if (name != 0) strcpy_s(name, strlen(s.name) + 1, s.name); } //重載賦值運算符 student& student::operator=(student& s) { id = s.id; score = s.score; delete[]name; name = new char[strlen(s.name) + 1]; strcpy_s(name, strlen(s.name) + 1, s.name); return *this; } void main() { student s1(1, "wang", 86); s1.printstu();
student s2(s1);//可以在定義時,直接初始化,自動調用復制構造函數 student s3; //因為使用了 等號運算符,所以如果不重載,則會自動調用默認的等號運算。 s3 = s1;
s2.printstu(); system("pause"); }
3、邏輯與和邏輯或,不能運算符重載
&& ,||, 重載他們不會產生短路規則。例子:t1 &&(t2+t3),前面的 t1 不成立,則不會執行后面的語句。