2011-05-13 61 views
16

我試圖在Visual Studio中的下列程序2010C++的析構函數的行爲

#include <iostream> 
using namespace std; 

class A { 
public: 
     int p; 

     /*A(){ 
      cout << "Constructor A" << endl; 
     }*/ 

     ~A(){ 
      cout << "Destructor in A" << endl; 
     } 
}; 

class D: public A 
{ 
public: 

     /*D(){ 
      cout << "Constructor D" << endl; 
     }*/ 

     ~D(){ 
      cout << "Destructor in D" << endl; 
     } 
}; 

int main() 
{ 
    D d = D(); 
    cout << "Exiting main" << endl; 
} 

,我得到的輸出是 -

Destructor in D 
Destructor in A 
Exiting main 
Destructor in D 
Destructor in A 

我無法理解爲什麼d類的析構函數A在執行「Exiting main」語句之前被稱爲 ?

我想另一件事 - 我註釋掉了d類的構造函數在上面的代碼,然後輸出作爲我 預期是 -

Constructor D 
Exiting main 
Destructor in D 
Destructor in A 

缺少什麼我在這裏?

回答

19

D d = D(); 

首先創建一個臨時的,未命名的對象,然後被複制到d。你看到的是臨時對象在聲明結束時被銷燬。指定的對象dmain()完成之後超出範圍時被銷燬。

如果您向D添加複製構造函數,您會看到它被調用。

當註釋掉構造函數時,我認爲你會看到預期的行爲,因爲編譯器可以做一些優化。

+0

沒有解釋爲什麼第二個示例不再打印出析構函數調用。 – Xeo 2011-05-13 06:49:26

+0

你可以知道它應該是什麼(: – 2011-05-13 06:50:04

+0

)編譯器只允許進行不可觀察的優化,即使它拷貝了elision,也應該打印該呼叫 – Xeo 2011-05-13 06:52:06