C++物件的構造、析構與拷貝構造
阿新 • • 發佈:2019-01-10
今天下午在研究虛擬函式的時候遇到了一個問題,覺得很有意思,記錄一下。
先看程式碼:
1 class Base 2 { 3 public: 4 Base(int value) 5 { 6 m_nValue = value; 7 cout << "object(" << this << "){" << this->m_nValue << "} is constructing!" << endl; 8 } 9 10 ~Base()11 { 12 cout << "object(" << this << "){" << this->m_nValue << "} is destroy!" << endl; 13 } 14 private: 15 int m_nValue; 16 }; 17 18 int main() 19 { 20 Base b(12); 21 (Base)b; 22 return 0; 23 }
列印結果:
為什麼會呼叫兩個解構函式?一個解構函式是可以理解的,為什麼要呼叫兩次?
其實這裡是呼叫了一次拷貝建構函式。調整一下程式碼
1 class Base 2 { 3 public: 4 Base(int value) 5 { 6 m_nValue = value; 7 cout << "object(" << this << "){" << this->m_nValue << "} is constructing!" << endl; 8 } 9 //新增部分 10 Base(const Base& b)11 { 12 this->m_nValue = b.m_nValue; 13 cout << "object(" << this << "){" << this->m_nValue << "} is copy constructing!" << endl; 14 } 15 //新增部分結束! 16 ~Base() 17 { 18 cout << "object(" << this << "){" << this->m_nValue << "} is destroy!" << endl; 19 } 20 private: 21 int m_nValue; 22 }; 23 24 int main() 25 { 26 Base b(12); 27 (Base)b; 28 return 0; 29 }
執行結果:
注意紅框裡邊標註的!(Base)b隱式的呼叫了拷貝建構函式和解構函式。
(Base)b的操作這樣看起來不是很舒服,我們把再修改一下程式碼
1 void fun(Base b) 2 { 3 //do nothing 4 } 5 int main() 6 { 7 Base b(12); 8 fun(b); 9 return 0; 10 }
執行結果:
b在進入fun這個函式的時候,發生了拷貝構造到析構的操作。這樣就很容易理解剛開始的問題:為什麼會出現兩次解構函式。
再修改一下程式碼,驗證一下:
1 void fun(Base& b) 2 { 3 //do nothing 4 cout << "fun" << endl; 5 } 6 int main() 7 { 8 Base b(12); 9 fun(b); 10 return 0; 11 }
執行結果。
這也就是為什麼要用引用 Base& b 而直接使用 Base b 的原因了。當然,最好還是加上const。
上述就是這個問題的記錄