簡體   English   中英

C ++默認副本構造函數

[英]c++ default copy constructor

我有以下代碼:

#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”。 您能解釋一下發生了什么嗎?

謝謝

這是怎么回事:

Uno k = u;

(復制) 初始化 ,它從Uno對象u復制構造Uno對象k 復制構造意味着將調用復制構造函數(在這種情況下,由編譯器隱式生成),而不是默認構造函數。

這就是為什么在初始化k不會輸出輸出消息的原因:構造函數不會被調用; 相反,將調用另一個 (隱式生成的)構造函數。

另請注意,以上聲明通常等同於此聲明:

Uno k;
k = u;

在最后一個代碼段中,表達式k = u是一個賦值 ,而不是一個初始化。 盡管兩個構造都使用=符號,但是您不應讓這混淆。

k是使用默認的復制構造函數創建的,該構造函數不會輸出X

嘗試添加以下內容:

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

並且您應該看到XY輸出。

在這種情況下,我相信不會調用構造函數,因為您沒有創建新的對象; 而是將舊對象復制到其他位置。

但是,由於您沒有使用指針,因此它們應該獨立。 更改一個不會影響另一個。

該代碼不會第二次運行構造函數,因為它不是在構建新的東西。 想象一下,創建u后,您對u字段進行了一些更改。 再次調用構造函數不會復制u,因此C ++不會這樣做。 這有點像復制照片-這樣做不會使相機關閉兩次,因為這可能會產生不同的圖像; 相反,您可以通過復印機運行它,這有點不同。

編輯:據我所知,它確實運行一個構造函數,而不是您編寫的那個。 假設我的隱喻中的相機具有內置的復印機,那當然不會引燃閃光燈。

這是因為您的類沒有復制構造函數。 如果沒有創建副本構造函數,則C ++調用默認的構造函數。 顯然沒有cout <<“ X”行。

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/

戴上我的書呆子帽子……除非您另外明確告訴編譯器,否則默認情況下,您始終擁有復制構​​造函數:

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 &);
        ...
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM