我們都知道兩個指針指向同一個變量時如果一個指針被釋放那麼另一個就會出問題 為了說明問題我做了一個很惡心的小例子 復制代碼 class C { public : C(int v) { ptrInt=new int; *ptrInt=v; valueInt = v; } ~C() { } void DelIntV() { valueInt=0; delete ptrInt; } C(const C& c) { } int * ptrInt; int valueInt; private: }; int main() { C c1(2); C c2(3); c2=c1; std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; c1.DelIntV(); std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; std::cin.get(); return 0; } 復制代碼 這是把c1賦值給了c2後把指針ptrInt的值輸出和valueInt輸出,再把c1的指針給delete,valueInt賦值為0 再輸出c2的ptrInt和valueInt就會發現指針有問題,看一下輸出結果: 已經不對了吧。 為了解決這樣的問題我第一個想到的就是重載操作符= 復制代碼 C& operator=(const C &c) { if(this!=&c) { delete ptrInt; ptrInt = new int; *ptrInt= *c.ptrInt; valueInt=c.valueInt; } return *this; } 復制代碼 完整代碼 復制代碼 class C { public : C(int v) { ptrInt=new int; *ptrInt=v; valueInt = v; } ~C() { } void DelIntV() { valueInt=0; delete ptrInt; } C(const C& c) { } int * ptrInt; int valueInt; C& operator=(const C &c) { if(this!=&c) { delete ptrInt; ptrInt = new int; *ptrInt= *c.ptrInt; valueInt=c.valueInt; } return *this; } private: }; int main() { C c1(2); C c2(3); c2=c1; std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; c1.DelIntV(); std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; std::cin.get(); return 0; } 復制代碼 再看一下輸出結果: 這下就正確了吧,但是如果 我們在main函數裡做一個修改 復制代碼 int main() { C c1(2); C c2=c1;//這裡直接賦值 std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; c1.DelIntV(); std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; std::cin.get(); return 0; } 復制代碼 這樣後錯誤就又和之前一樣了,為什麼呢, 編譯器將在c類裡找一個副本構造器(copy constructor)如果找不到它會自己創建一個, 即使我們對操作符=進行了重載也沒有用,由編譯器自己創建的副本構造器仍會以"逐們復制" 的方式把c1賦值給c2 這樣我們還要重新實現這個副本構造器, className(const className &cn); 我是這樣做的 C(const C& c) { *this=c; } 這裡的=其實就是調用的重載的=方法 完整代碼 復制代碼 class C { public : C(int v) { ptrInt=new int; *ptrInt=v; valueInt = v; } ~C() { } void DelIntV() { valueInt=0; delete ptrInt; } C(const C& c) { *this=c; } int * ptrInt; int valueInt; C& operator=(const C &c) { if(this!=&c) { delete ptrInt; ptrInt = new int; *ptrInt= *c.ptrInt; valueInt=c.valueInt; } return *this; } private: }; int main() { C c1(2); C c2=c1;//這裡直接賦值 std::cout<<"ptrInt "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; c1.DelIntV(); std::cout<<"address "<<c2.ptrInt<<" value "<<*c2.ptrInt<<std::endl; std::cout<<"valueInt "<<c2.valueInt<<std::endl; std::cin.get(); return 0;