2011-06-29 97 views
3

如果我寫C++類型複製初始化

T t = T(); 

T是一個類。

我認爲這是調用T的默認構造函數,然後調用複製賦值操作符。 但編譯器被允許擺脫作業。

我試圖找到用C++標準寫的這種行爲的描述,但我找不到它。 你能指點我在標準中的正確位置嗎?

我問這個,因爲我被要求更換此:

T t; 

T t = T(); 

因爲編碼規則檢查程序。

它發生的T類是不可複製的,並有一個私人拷貝構造函數和複製賦值操作符...所以我想看到,在這種情況下,編譯器實際上總是擺脫副本。

編輯: 我一直在誤導的奇怪的東西: 的noncompyable類實際上是從boost ::不可複製 在這種情況下它編譯繼承。 但是,如果我聲明覆制構造函數和複製賦值運算符是私有的,它不會編譯。例如 。這將編譯:

class BA 
{ 
protected: 
    BA() {} 
    ~BA() {} 
private: 
    BA(const BA&); 
    const BA& operator=(const BA&); 
}; 

class A : BA 
{ 
}; 

int main(void) 
{ 
    A a = A(); 
    return 0; 
} 

及以下不:

class A 
{ 
public: 
    A() {} 
    ~A() {} 
private: 
    A(const A&); 
    const A& operator=(const A&); 
}; 

int main(void) 
{ 
    A a = A(); 
    return 0; 
} 
+0

什麼是編碼規則?對於一個類類型(帶有一個拷貝構造函數,只是拷貝),'T t'與'T t = T()'相同。如果你的代碼檢查器無法檢測到這一點,那麼你應該改變你的檢查器。你會爲無法複製的第三方庫類型做些什麼? –

回答

1

既然你問了C++標準的引用,那就是:

12。8複製類對象

* 當滿足特定條件時,一種實現被允許省略一個類對象的拷貝結構,即使拷貝構造和/或析構函數爲對象有​​副作用。在這種情況下,該實現將被忽略的複製操作的來源和目標視爲簡單地引用同一對象的兩種不同方式,並且該對象的銷燬發生在兩個對象將具有的時間的晚些時候被破壞沒有optimization.111)複製操作的這個省音被允許在下列情況下(這可以合併,以消除多個副本):

- return語句中與類返回類型的功能,當表達式是具有與函數返回類型相同cv-unqualified類型的非易失性自動對象的名稱時,可以通過將自動對象直接構造到函數的返回值中來省略複製操作。

- 當尚未結合至參考(12.2)臨時類對象將被複制到一個類對象具有相同的CV-不合格型,複製操作可以通過直接構建臨時對象省略成省略副本的目標 *

實施例:

class Thing 
{ 
    public: 
     Thing(); 
     ˜Thing(); 
     Thing(const Thing&); 
}; 

Thing f() 
{ 
    Thing t; 
    return t; 
} 

Thing t2 = f(); 

這裏省音的標準可以被組合以消除兩個調用類東西的拷貝構造:
將本地自動對象t複製到函數f()的返回值的臨時對象中,並將該臨時對象複製到對象t2中。實際上,本地對象t的構造可以被看作是直接初始化全局對象t2,並且該對象的銷燬將在程序出口處發生。

1

這就是所謂的Return Value Optimization。本文還在腳註中提到了相關的C++標準段落。

如果您想要更精確地控制行爲,比如通過alloca自己分配臨時對象,然後調用placement new操作符,那麼在處理對象時可以更明確。

7

它是無參數的構建臨時然後複製構建t,不能複製分配給它(8.5/14)。

拷貝構造函數可以被省略,但必須是可訪問反正(12.8/14-15)

1

在C++ 0x中,你可以用T t{};取代T t;