1. 程式人生 > >C++物件的構造、析構與拷貝構造

C++物件的構造、析構與拷貝構造

 

今天下午在研究虛擬函式的時候遇到了一個問題,覺得很有意思,記錄一下。

先看程式碼:

 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。

上述就是這個問題的記錄