2012-07-07 28 views
2
class Error1 
{ 

public: 

int errorcode; 
Error1(int x):errorcode(x){ cout<<"CTOR Error1"<<endl; } 
//Error1(Error1& obj){ 
// errorcode = obj.errorcode; 
// cout<<"CopyCTOR Error1"<<endl; 
//} 
~Error1(){cout<<"DTOR Error1"<<endl; } 
}; 

void fun() 
{ 
cout<<"Inside fun"<<endl; 
throw(Error1(5)); 
} 

int main() 
{ 
try{ 

    fun(); 
} 
catch(Error1& eobj) 
{ 
    cout<<"Error1 type occured with code:"<<eobj.errorcode<<endl; 
} 
cin.get(); 

} 

OUTPUT:通過引用捕獲異常時臨時對象不會創建?

Inside fun 

CTOR Error1 

DTOR Error1 

Error1 type occured with code:5 

DTOR Error1 

此輸出指示一個ERROR1對象是catch處理構造副本。由於複製構造函數沒有爲Error1對象定義,所以使用默認拷貝構造函數。

當我取消註釋評論部分定義複製構造函數我得到以下輸出。

Inside fun 

CTOR Error1 

Error1 type occured with code:5 

DTOR Error1 

爲什麼只有一個DTOR被調用?即使異常被引用引用,我相信仍然會創建一個臨時對象。

+0

看起來輸出依賴於編譯器和異常運行時實現。例如,gcc 4.3.4不會爲您的第一個代碼示例使用默認的複製構造函數生成任何臨時對象。你可以在這裏看到一個例子:http://ideone.com/9QyLf – Jason 2012-07-07 06:26:59

+0

首先,如果你定義你的DTOR爲虛擬的,你將得到與第二個相同的第一個行爲。 – klement 2012-07-07 06:28:15

+0

@klement:這裏沒有多態行爲發生,所以我相信使用'virtual' DTOR是不必要的 – Jason 2012-07-07 06:29:30

回答

1

你使用什麼編譯器?

當您使用Error1& obj參數引入(即取消註釋)版本的複製構造函數時,代碼應該失效。 throw應該能夠創建其參數的副本,而您的拷貝構造函數的版本將禁用臨時對象的拷貝。代碼格式不正確。如果您的編譯器接受它,可能是因爲它非法允許將非常量引用綁定到臨時對象(我懷疑它是啓用了擴展的MSVC++編譯器)。

原始實驗按照設想/允許的方式工作。 throw的參數被複制到一個內部臨時參數,後者用於初始化參數catch。儘管編譯器可以直接使用原始臨時文件,但相應地延長了其使用期限。

+1

如果他將其定義爲私人,則它變爲無效。他仍然可以依靠默認拷貝CTOR。 – klement 2012-07-07 06:31:33

+0

@klement:來自OP的用戶定義的CTOR採用非''contst'參考類型,這意味着它不能接受作爲參數的臨時... – Jason 2012-07-07 06:32:24

+0

@klement:首先,聲明任何複製構造函數禁用編譯器 - 提供了一個(這可能是你所謂的「默認」)。其次,只要引用參數是非const的,即使使用公共拷貝構造函數,代碼也是無效的。正如我已經說過的,這種複製構造函數不能用於複製臨時對象。 – AnT 2012-07-07 06:34:14

-1

可能還有其他錯誤,但我現在看到的是throw(Error1(5));創建了Error1類型的臨時(或rvalue)。你想要一個lvalue,這意味着你應該做throw(*new Error1(5));(我相信這會造成內存泄漏,但我可能是錯的),或者你可以創建一個全局對象,然後拋出它。

PS:我很想知道如果有人想評論,throw(*new Error1(5));確實會造成內存泄漏。 catch破壞它捕獲的對象嗎?如果是這樣,我認爲你應該沒問題,只要你需要創建新的Error1即可。

+0

你會發現什麼?你正在拋棄解除引用的指針嗎?所以如果你的catch類似catch(Error1 obj)或catch(Error1&obj)它會導致內存泄漏。 – hackrock 2012-07-07 07:02:32

+0

如果你手動刪除了'Error1',它會不會泄漏內存? – anthropomorphic 2012-07-07 07:04:28

+0

我相信你不能做手動刪除,除非你拋出指針,並通過指針捕獲 – hackrock 2012-07-07 07:07:03