2012-02-19 42 views
0

考慮以下代碼:雜臨時對象T()

int main() 
{ 
    int i(6); //this will result in i==6,but consider next initializations 

    int j(int()); 

    T * p2 = new T(); 
} 

我發現的j的值是1,但是這應該是0,因爲int()是臨時與值等於0

此外,new運算符的語法爲new typename,但這裏T()將是臨時對象而不是類型名稱。

+1

你很困惑,'new T()'不會動態地分配一個'T'對象並對它進行初始化,它不會創建一個臨時對象。你究竟在做什麼? – 2012-02-19 07:06:40

+0

這應該是關閉的,現在毫無疑問,如果添加了一個問題,它將成爲Nawaz答案中的鏈接或http://stackoverflow.com/questions/2671532/non-copyable-對象和值初始化的g - vs - msvc和http://stackoverflow.com/questions/6298001/value-initializing-an-automatic-object – 2012-02-19 07:08:10

+0

事實上,TJ剛剛問兩小時前的其中一個問題: http://stackoverflow.com/questions/9346687/value-initialization-for-automatic-variables **下一次閱讀評論中留下的問題鏈接,TJ! – 2012-02-19 07:08:33

回答

4
int j(int()); 

這沒有聲明一個對象。相反,它聲明瞭一個函數作爲參數,並返回int。該類型的需要作爲參數的函數是這樣的:

typedef int (*funtype)(); 

也就是說,是,它返回int,並採取毫無作爲自變量的函數。

這種聲明的解析是俗稱:


而在new語法,T()不創建臨時對象。這不是如何被看到的。相反,您必須查看整個表達式new T(),它首先爲T類型的對象分配內存,然後在該內存中構造對象。如果T是用戶定義的類型,則在分配內存之後,它會調用默認的構造函數來構造對象。

+4

而解決的辦法是使用額外的括號來製作它是一個無效的函數聲明:'int j((int()));',或者避免語法:'int j = int();'。 – GManNickG 2012-02-19 06:56:53

+0

@nawaz:那麼secoond問題 – 2012-02-19 07:03:59

+0

@ T.J .:更新了答案。 – Nawaz 2012-02-19 07:18:36

1

新操作符的語法也是typename * variable_name = new typename,但這裏T()將是一個臨時對象,但不是類型名稱。

與最苦惱的解析類似,T()根據上下文具有不同的含義。它並不總是產生一個臨時的,但通常會初始化一些新的匿名對象或子對象。如果如果顯示newT()身體之前出現在一個構造T(),或

  • 指針所指示的對象的對象可能是

    • 臨時如果T()是在表達,
    • 基子對象。請注意,指針有一個名稱,但該對象是匿名的。

    new Tnew T()做稍微不同的事情:對於某些類型的,new T葉值初始化。 (官方術語是默認初始化。)基本子對象或臨時對象沒有相應的語法結構:基本子對象通過省略初始化程序進行默認初始化,臨時對象不允許默認初始化。區別很小,因爲在所有這些情況下,如果您定義了構造函數將調用,並且始終應定義構造函數,並且應始終初始化所有成員。例外情況是基本類型,如int和簡單結構如std::array<char, 1000>

    爲了安全起見,最好避免使用new T而使用new T()只是爲了確保在沒有構造函數的情況下可以很好地清零。