2011-08-25 208 views
3

做了C++編譯器自動轉換:C++優化構建和複製到複製構造函數嗎?

MyObject object2 = object1; 

MyObject object2(object1); 

抑或是像對待:

MyObject object2; 
object2 = object1; 

+0

如果這是一個真正的性能問題,您可能已經知道答案。一般來說,不要擔心這樣的微觀優化,除非它處於瓶頸狀態,並且你發現它會導致真正的問題。如果您想知道編譯器是否執行優化X,則假定答案是肯定的。 –

+0

我想我也對最佳做法感興趣。它是否是微型優化很大程度上取決於對象的大小以及創建它的函數的大小/頻率。 –

+0

@PP - 是的,這可能是一個優化_does_的程度取決於這些事情。這就是爲什麼你不應該打擾優化,除非你已經分析,發現它是一個問題。 –

回答

2

你可以試試這個,看看具體的行爲:

#include <iostream> 

class MyObject { 
public: 
    MyObject() { 
     std::cout << "MyObject()" << std::endl; 
    } 
    MyObject(const MyObject& other) { 
     std::cout << "MyObject(const MyObject& other)" << std::endl; 
    } 
    MyObject& operator=(const MyObject& other) { 
     std::cout << "operator=(const MyObject& other)" << std::endl; 
     return *this; 
    } 
}; 

int main() { 
    MyObject object1; 
    MyObject object2 = object1; 
    MyObject object3(object1); 
    MyObject object4; 
    object4 = object1; 
} 

輸出:

MyObject() 
MyObject(const MyObject& other) 
MyObject(const MyObject& other) 
MyObject() 
operator=(const MyObject& other) 

除此之外,我建議你閱讀What is The Rule of Three?

+0

感謝您提供清晰的示例代碼。答案有衝突毋庸置疑。 –

8

是的,這是第一個。這不是一個「優化」;它們是調用複製構造函數的兩種不同的語法。

如果您想證明它,請嘗試爲MyObject定義一個專用賦值運算符。代碼仍然應該編譯,這證明它不能等同於第二種機制。

+2

雖然有關於顯式拷貝構造函數的問題嗎? –

+0

@Kerrek:是的...... –

+2

@Kerrek:是的,用equals初始化不會考慮顯式構造函數。 –

1
MyObject object2 = object1; 

副本初始化。這將調用複製構造函數,如果object1MyObject類型。

object1如果是不同類型的,然後它要麼做從object1的隱式轉換到MyObject,然後或者複製構造從object2,或執行隱式轉換直接進入object2和跳過拷貝構造。在這兩種情況下,複製構造函數(或C++ 11中的移動構造函數)都必須是可訪問的。

+0

我不認爲C++ 11 _requires_移動構造函數,是不是? –

+0

要在C++ 11中執行拷貝初始化,那麼你必須有一個複製或移動構造函數,或者兩者兼有 –

+0

您的最後一句暗示移動構造函數必須在C++ 11中可訪問,只要確保它清楚您的意思即可 –

2

什麼被稱爲與MyObject object2 = object1;是一個構造因爲這是初始化。這與賦值運算符無關。

但是,您建議從MyObject object2 = object1;轉換爲MyObject object2(object1);的轉換不會發生,因爲這兩個初始化語法並不相同。它們的相似之處在於它們都通過調用構造函數來初始化對象,但它們有細微的差別。

如果您有:

struct MyObject { 
    explicit MyObject(MyObject const&); 
}; 

然後MyObject object2 = object1;是形成不良的,但MyObject object2(object1);是良好的。