2013-06-29 80 views
0

我有以下代碼:C++默認的拷貝構造函數

#include <iostream> 
    #include <string> 
    using namespace std; 
    class Uno { 
    public: Uno() { cout << "X"; } 
    }; 



    int main() 
    { 
      Uno u; 
      Uno k=u; 

      return 0; 
    } 

所以從我個人理解,代碼Uno k=u;將創建的u副本。它看起來像構造函數被調用兩次。我期待「XX」,但程序只輸出「X」。你能解釋一下發生了什麼事嗎?

謝謝

+0

這個不清楚。你的構造函數被調用一次還是兩次? –

回答

1

k正在使用默認的拷貝構造函數它不輸出的X創建。

嘗試添加此:

Uno(const Uno&) { cout << "Y"; } 

,你應該看到XY輸出代替。

1

在這種情況下,我相信構造函數沒有被調用,因爲你沒有創建一個新的對象;相反,您正在將舊對象複製到其他位置。

但是,由於您不使用指針,它們應該是獨立的;更改爲一個不會影響另一個。

該代碼不會再次運行構造函數,因爲它不構建新的東西。想象一下,創建後你已經對u域進行了一些改變。再次調用構造函數不會生成u的副本,因此C++不會這樣做。這有點像複製照片 - 這樣做不會讓你的相機出現兩次失敗,因爲這可能會產生不同的圖像;相反,你通過複印機運行它,這是不同的。

編輯:正如我已被通知,它確實運行a構造函數,只是不是你寫的。假設我比喻中的相機有一個內置的複印機,當然這不會引起閃光。

+1

OP *是*通過copy-construction –

+0

創建一個新對象謝謝,這個比喻很有道理。 – focusHard

3

發生了什麼事是這樣的:

Uno k = u; 

爲A(禁止複製)初始化,其拷貝構造Uno對象kUno對象u。複製構造意味着複製構造函數(在本例中由編譯器隱式生成)被調用,而不是默認的構造函數。

這就是爲什麼您輸出的消息在k初始化過程中沒有得到打印:您的構造函數沒有被調用;相反,另一個(隱式生成)構造函數被調用。

還要注意的是,上面的聲明等效於這個一般

Uno k; 
k = u; 

在該最後片段中,表達k = u分配,而不是一個初始化。儘管這兩個構造都使用了=符號,但不應該讓你迷惑。

1

這是因爲你的類沒有複製構造函數。如果沒有創建拷貝構造函數,那麼C++將調用默認的構造函數。這顯然不具有「X」行的cout < <。

Uno u;  // your constructor called, --> X to output 
Uno k = u; // default copy constructor called 

但是拷貝構造函數是沒有意義的,如果你沒有成員變量。

所以我們可以說這是你想要什麼:

#include <iostream> 
#include <string> 

using namespace std; 

class Uno 
{ 
    public: 

    string text; 

    // constructor 
    Uno() 
    { 
     text = "X"; 
     cout << text; 
    } 

    // copy constructor 
    Uno(const Uno &o) 
    { 
     text = o.text; 
     cout << text; 
    } 
}; 

int main() 
{ 
     Uno u;  // call constructor -> X 
     u.text = "Y"; // change text in constructed object 
     Uno k=u;  // create new object via calling copy constructor --> Y 
         // so u.text copied to k.text 

     return 0; 
} 

我建議learncpp.com的文章,他們是非常有用的,讓事情變得簡單。

關於拷貝構造函數和賦值運算符

更多信息: http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/

0

我的學究把帽子一會...除非你明確地告訴編譯器,否則,你總是有,默認情況下,拷貝構造函數:

Uno(const Uno & other); 

和賦值運算符:

Uno & operator=(const Uno & other); 

你是否要求與否。如果不定義任何其他構造函數,你也可以得到默認的構造函數:

Uno(); 

既然你已經定義了無參數的構造函數,你會被用來代替去年的默認。

當你定義的變量:

Uno u; 

你的構造函數是用來初始化對象實例。當你做任務:使用

Uno k=u; 

賦值運算符。

如何避免複製或分配對象?聲明它們是私人的,並且不需要執行它們:

class Uno 
{ 
private: 
    Uno(const Uno &); 
    Uno & operator=(const Uno &); 
     ... 
}; 
+0

你確定在'Uno k = u;'賦值運算符是否被使用? –