2012-09-27 44 views
1

我讀的地方(找不到現在源)爲什麼`拋出MyClass'不起作用,拋出MyClass()'呢?

MyClass *p1 = new MyClass; 

MyClass *p2 = new MyClass(); 

基本上是相等的,前提是MyClass提供一個默認的構造函數。編譯器明白我想要做什麼並添加空括號。

如果是這樣的話,爲什麼不讓我寫

throw MyException; 

,但必須使用

throw MyException(); 

? (是的,在一行的開頭問號。)

多補充一些混亂,C++ FAQ表明,第二用例(new MyClass())不會調用構造函數,但要求與operator(),而不是定義的函數。

+5

C++中一個有趣的怪癖:你不能擁有值初始化的自動對象,並且你不能擁有默認初始化的臨時對象。 –

回答

3

編譯器明白我想做的事情,並增加了空括號。

不,它不;這兩個表達式並不完全相同。區別在於對象是如何初始化的:第一個使用默認初始化,第二個使用值初始化。所以它們對於定義默認構造函數的類是等價的;否則,第一個將使POD對象未初始化,而第二個將初始化爲零。

爲什麼我不允許寫throw MyException;

MyException()是一個表達式,它創建一個值初始化的臨時對象;你可以拋出它,就像你可以拋出任何其他合適表達式的值一樣。

MyException不是表達式;它只是一個類型名稱。你只能拋出一個表達式的值,所以throw MyException;無效。沒有辦法創建默認初始化臨時。

爲了增加一些混淆,C++ FAQ建議第二個用例(new MyClass())不調用構造函數,而是調用用operator()定義的函數。

不,它不。它表示像List x();這樣的聲明聲明瞭返回類型爲List的函數,而不是(可能會認爲)類型爲List的值初始化對象。它與新表達或operator()無關。

+0

爲了確保我理解正確:_「第一個使用默認初始化,而第二個使用值初始化。」_這意味着第一個調用默認構造函數,而第二個創建一個臨時對象,並使用賦值運算符? –

+0

@ peter.slizik:否。如果類有一個不平凡的默認構造函數,那麼兩者都會使用它。如果沒有,則默認初始化將使POD對象不初始化,而值初始化將初始化它們爲零值。這兩者都不會創建臨時或使用任務。 –

+0

@ peter.slizik:查看[這個問題](http://stackoverflow.com/questions/1613341)瞭解更多關於C++中各種初始化類型的細節。 –

0

常見問題中列出的情況有所不同,不適用於此。

MyException只是第一種情況下的類型名稱,並在第二種情況下創建了一個變量。這只是語法。同

MyException ex = MyException; 

不會編譯,但

MyException ex = MyException(); 

會。常見問題示例僅示出相當於:

​​

這確實是一個函數聲明,而:

MyException ex; 

會。

有沒有辦法,

throw MyException(); 

MyException ex = MyException(); 

可以解釋爲函數聲明,所以他們的工作。

1

因爲你沒有拋出new異常,而是構造它。

考慮以下幾點:

MyException exception = MyException(); // works 
MyException exception = MyException; // doesn't work 

new MyException; // works 
new MyException();// works 
相關問題