C++三大函數:html
函數模樣:~S()ide
當一個對象超出做用域或執行delete的時候,析構函數就被調用。函數
函數模樣:S(const S& s)this
如下狀況,複製構造函數均會被調用:spa
聲明的同時初始化:指針
S s1 = s2; //注意此時雖然出現=,可是不是調用operator=哦 S s1(s2);
調用函數時使用按值傳遞(而不是按引用傳遞)code
void f(S s); S s1; f(s1);
經過值返回對象htm
S f() { S s1; return s1; }
函數模樣:const S& operator=(const S& s)對象
當=應用於兩個已經構造的對象時,就調用複製賦值運算符operator=。blog
S s1; s1 = s2; //注意與S s1 = s2; 的區別
三大函數不手動實現的時候,會使用默認的版本。好比operator=的默認版本會依次爲數據成員複製,若是是基本數據類型天然沒什麼問題,但當數據成員含有指針的時候,operator的只會進行淺複製
,即只是指針自己被複制,而不是指針所指向的內容被複制。見下例。
class S { public: int *p; S(int x=0){p=new int(x);} }; void f() { S s1(2), s2; S s3 = s1; s2 = s1; *s1.p=3; cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl;//3 3 3 }
很明顯這不是咱們想要的,咱們想讓不一樣的對象的值不互相影響,此時須要實現深複製
,見下例。
class S { public: int *p; S(int x=0){p=new int(x);} S(const S& rhs) { p = new int(*rhs.p); } const S& operator=(const S& rhs) //rhs=right-hand side { if (this != &rhs) //檢查是否複製自身 *p = *rhs.p; return *this; } }; void f() { S s1(2), s2; S s3 = s1; s2 = s1; *s1.p=3; cout << *s1.p << ' '<< *s2.p << ' ' << *s3.p << endl; //3 2 2 }