2012-03-31 35 views
7

在這個代碼片段中,實際調用哪個構造函數?這裏調用了哪個構造函數?

Vector v = getVector(); 

矢量有拷貝構造函數,默認的構造函數和賦值操作符:

class Vector { 
public: 
    ... 
    Vector(); 
    Vector(const Vector& other); 
    Vector& operator=(const Vector& other); 
}; 

getVector的價值回報。

Vector getVector(); 

代碼使用C++ 03標準。

代碼片段看起來像它應該調用默認的構造函數,然後賦值運算符,但我懷疑這個聲明是使用複製構造函數的另一種形式。哪個是對的?

回答

8

=出現在初始化中時,它調用複製構造函數。一般形式與直接調用拷貝構造函數並不完全相同。在聲明T a = expr;中,會發生什麼情況是,如果expr是T類型,則會調用複製構造函數。如果expr不是T類型的,那麼首先進行隱式轉換,如果可能的話,然後將複製構造函數作爲參數調用。如果隱式轉換不可行,那麼代碼是不合格的。

取決於如何getVector()結構,副本可能被優化掉,那就是在函數內部創建的對象是被存儲在訴相同的物理對象。

+0

一個毫無價值的規則是拷貝構造函數必須是可訪問的(例如public),即使拷貝構造本身最終被刪除。因此,可能使拷貝構造函數私有的代碼將無法編譯,並使其成爲公衆將編譯,但拷貝構造函數將不會被調用。 – 6502 2012-03-31 16:22:05

+0

「存儲在v中的相同物理對象」 - 相反,在函數內部創建的對象與「v」是相同的物理對象。我通常說的是'v'是一個對象的名稱,或'v'是對象,而不是「對象存儲在'v'」。這個copy elision的通常實現是'getVector'的調用者傳遞一個指針作爲一個額外的隱藏參數,'getVector'構造它在那個地址的返回值。在這種情況下,標準允許調用代碼將'&v'作爲隱藏參數傳遞。 – 2012-03-31 17:47:42

0

拷貝構造函數實際上得到這個消隱情況(檢查this),只是默認的構造函數最終得到所謂

編輯:

構造函數只是偶爾省略掉,按照本雅明的答案。出於某種原因,我在閱讀時直接調用構造函數。

2

假設你有沒有做過一些病理你是顯示的代碼外,你的宣言是一份初始化,而這個規則的第二部分適用:

13.3.1.3 Initialization by constructor [over.match.ctor] 

1 When objects of class type are direct-initialized (8.5), or copy-initialized from an 
    expression of the same or a derived class type (8.5), overload resolution selects the 
    constructor. For direct-initialization, the candidate functions are all the constructors 
    of the class of the object being initialized. For copy-initialization, the candidate 
    functions are all the converting constructors (12.3.1) of that class. The argument 
    list is the expression-list within the parentheses of the initializer. 

對於一個簡單的測試案例見禮Bendersky的帖子,在這裏:http://eli.thegreenplace.net/2003/07/23/variable-initialization-in-c/

1

永遠記住規則:
無論何時,正在創建並在同一個語句中給定的一些值的對象,那麼它是從未的分配。

進一步添加,

情況1:

Vector v1; 
Vector v(v1); 

情況2:

Vector v = getVector(); 

在上述兩種格式案例1直接初始化案例2被稱爲拷貝初始化

如何複製初始化工作?
複印初始化構建的隱式轉換序列:它試圖的getVector()返回值轉換爲Vector類型的對象。然後,它可以創建的對象複製到被初始化的對象,所以它需要一個訪問的拷貝構造函數。

相關問題