c ++默认复制构造函数

时间:2013-06-29 00:41:09

标签: c++ constructor copy default

我有以下代码:

#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”。你能解释一下发生了什么吗?

谢谢

5 个答案:

答案 0 :(得分:3)

这是怎么回事:

Uno k = u;

是(复制 - )初始化,它从Uno对象k复制构造Uno对象u。复制构造意味着调用复制构造函数(在这种情况下由编译器隐式生成),而不是默认构造函数。

这就是为什么在k初始化期间不输出您输出的消息:您的构造函数不会被调用;相反,调用另一个(隐式生成的)构造函数。

另请注意,上述声明通常与此相同:

Uno k;
k = u;

在最后一个片段中,表达式k = u赋值,而不是初始化。虽然这两个构造都使用=符号,但您不应该让它混淆。

答案 1 :(得分:1)

正在使用默认的复制构造函数创建

k,该构造函数不输出X

尝试添加此内容:

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

您应该看到XY输出。

答案 2 :(得分:1)

在这种情况下,我认为没有调用构造函数,因为你没有创建一个新对象;相反,您正在将旧对象复制到其他位置。

但是,由于你没有使用指针,它们应该是独立的;改变为一个不会影响另一个。

代码第二次不运行构造函数,因为它没有构建新的东西。想象一下,在创建它之后,你已经对你的一个领域做了一些改变。再次调用构造函数不会复制u,因此C ++不会这样做。这有点像复制一张照片 - 这样做不会让你的相机两次熄灭,因为这会产生不同的画面;相反,你通过复印机运行它,这是不同的。

编辑:正如我所知,它确实运行了一个构造函数,而不是你编写的那个。假设我的比喻中的相机有一个内置复印机,当然不会闪光。

答案 3 :(得分:1)

这是因为你的类没有复制构造函数。如果没有创建复制构造函数,则C ++调用默认构造函数。这显然没有cout&lt;&lt;“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/

答案 4 :(得分: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 &);
        ...
};