简体   繁体   English

C ++默认副本构造函数

[英]c++ default copy constructor

I have the following code: 我有以下代码:

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



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

            return 0;
    }

So from what I understand, the code Uno k=u; 因此,据我了解,代码Uno k=u; would create a copy of u. 将创建一个u的副本。 It seems like the constructor is called twice. 似乎构造函数被调用了两次。 I'm expecting "XX", but the program only outputs "X". 我期望“ XX”,但是程序仅输出“ X”。 Can you please explain what is going on? 您能解释一下发生了什么吗?

thank you 谢谢

What is going on is that this: 这是怎么回事:

Uno k = u;

Is a (copy-) initialization , which copy-constructs the Uno object k from the Uno object u . (复制) 初始化 ,它从Uno对象u复制构造Uno对象k Copy-construction means that the copy constructor (implicitly generated by the compiler, in this case) is invoked, not the default constructor. 复制构造意味着将调用复制构造函数(在这种情况下,由编译器隐式生成),而不是默认构造函数。

This is why the message you output does not get printed during the initialization of k : your constructor does not get called; 这就是为什么在初始化k不会输出输出消息的原因:构造函数不会被调用; instead, another (implicitly generated) constructor is invoked. 相反,将调用另一个 (隐式生成的)构造函数。

Also notice, that the above declaration is not equivalent to this in general: 另请注意,以上声明通常等同于此声明:

Uno k;
k = u;

In this last snippet, the expression k = u is an assignment , not an initialization. 在最后一个代码段中,表达式k = u是一个赋值 ,而不是一个初始化。 Although both constructs use the = sign, you should not let that confuse you. 尽管两个构造都使用=符号,但是您不应让这混淆。

k is being created using the default copy constructor which doesn't output an X . k是使用默认的复制构造函数创建的,该构造函数不会输出X

Try adding this: 尝试添加以下内容:

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

And you should see XY output instead. 并且您应该看到XY输出。

In this case, I believe that the constructor is not called, because you are not creating a new object; 在这种情况下,我相信不会调用构造函数,因为您没有创建新的对象; rather, you are copying an old object to a different location. 而是将旧对象复制到其他位置。

However, as you are not using pointers, they should be independent; 但是,由于您没有使用指针,因此它们应该独立。 changes to one will not affect the other. 更改一个不会影响另一个。

The code does not run the constructor a second time, because it is not building something new. 该代码不会第二次运行构造函数,因为它不是在构建新的东西。 Imagine that you had made some change to a field of u after it was created. 想象一下,创建u后,您对u字段进行了一些更改。 Calling the constructor again would not make a copy of u, so C++ does not do that. 再次调用构造函数不会复制u,因此C ++不会这样做。 It's sort of like copying a photograph - doing so does not make your camera go off twice, because that could produce a different picture; 这有点像复制照片-这样做不会使相机关闭两次,因为这可能会产生不同的图像; instead, you run it through the copier, which is something different. 相反,您可以通过复印机运行它,这有点不同。

EDIT: as I've been informed, it does run a constructor, just not the one that you've written. 编辑:据我所知,它确实运行一个构造函数,而不是您编写的那个。 Suppose that the camera in my metaphor had a built-in copier, which of course would not set off the flash. 假设我的隐喻中的相机具有内置的复印机,那当然不会引燃闪光灯。

It is because your class doesn't have a copy constructor. 这是因为您的类没有复制构造函数。 If no copy constructor created, then C++ calls the default one. 如果没有创建副本构造函数,则C ++调用默认的构造函数。 Which is obviously doesn't have the cout<<"X" line. 显然没有cout <<“ X”行。

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

However the copy constructor does not make sense if you don't have member variables. 但是,如果没有成员变量,则复制​​构造函数没有任何意义。

So let's say this is what you want: 所以说这就是你想要的:

#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;
}

I recommend learncpp.com articles, they are very useful and keep things simple. 我推荐Learncpp.com文章,它们非常有用,可以使事情简单。

More info about copy constructor and assignment operator: http://www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/ 有关复制构造函数和赋值运算符的更多信息: http : //www.learncpp.com/cpp-tutorial/911-the-copy-constructor-and-overloading-the-assignment-operator/

Putting on my pedant hat for a moment ... Unless you explicitly tell the compiler otherwise, you always have, by default, the copy constructor: 戴上我的书呆子帽子……除非您另外明确告诉编译器,否则默认情况下,您始终拥有复制构​​造函数:

Uno(const Uno & other);

and the assignment operator: 和赋值运算符:

Uno & operator=(const Uno & other);

whether you ask for them or not. 是否要求他们。 If you don't define any other constructors, you also get the default constructor: 如果您没有定义任何其他构造函数,那么您还将获得默认的构造函数:

Uno();

Since you've defined the no-argument constructor, yours will be used instead of that last default. 由于定义了无参数构造函数,因此将使用您的无参数构造函数代替最后的默认构造函数。

When you define the variable: 定义变量时:

Uno u;

your constructor is used to initialize the object instance. 您的构造函数用于初始化对象实例。 When you do the assignment: 执行作业时:

Uno k=u;

the assignment operator is used. 使用赋值运算符。

And how, you might ask, do I prevent copying or assigning an object? 您可能会问,如何防止复制或分配对象? Declare them to be private, and do not implement them: 声明它们是私有的, 不要实现它们:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM