C++ c++;默认副本构造函数

C++ c++;默认副本构造函数,c++,constructor,copy,default,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; } #包括 #

我有以下代码:

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



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

            return 0;
    }
#包括
#包括
使用名称空间std;
乌诺班{

public:Uno(){cout
k
正在使用默认的复制构造函数创建,该构造函数不输出
X

尝试添加以下内容:

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

Uno(const Uno&){cout
k
正在使用默认的复制构造函数创建,该构造函数不输出
X

尝试添加以下内容:

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

Uno(const Uno&){cout在本例中,我认为构造函数没有被调用,因为您没有创建新对象;相反,您正在将旧对象复制到不同的位置

但是,由于不使用指针,它们应该是独立的;对其中一个指针的更改不会影响另一个指针

<>代码不第二次运行构造函数,因为它没有创建新的东西。想象一下,在创建一个U字段之后,你已经对它进行了一些改变。再次调用构造函数不会复制U,所以C++不这样做。它有点像复制照片——这样做不会使相机两次关闭。因为这可能会产生不同的图片;相反,你可以通过复印机运行它,这是不同的


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

在这种情况下,我相信没有调用构造函数,因为您不是在创建新对象,而是在复制旧对象ct扫描到不同的位置

但是,由于不使用指针,它们应该是独立的;对其中一个指针的更改不会影响另一个指针

<>代码不第二次运行构造函数,因为它没有创建新的东西。想象一下,在创建一个U字段之后,你已经对它进行了一些改变。再次调用构造函数不会复制U,所以C++不这样做。它有点像复制照片——这样做不会使相机两次关闭。因为这可能会产生不同的图片;相反,你可以通过复印机运行它,这是不同的


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

发生的事情是:

Uno k = u;
是一个(复制-初始化,它从
Uno
对象
u
复制构造
Uno
对象
k
。复制构造意味着调用复制构造函数(在本例中由编译器隐式生成),而不是默认构造函数

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

另外请注意,上述声明一般不等同于此:

Uno k;
k = u;

在最后一个代码段中,表达式
k=u
是一个赋值,而不是一个初始化。尽管两个构造都使用了
=
符号,但您不应该让它迷惑您。

发生的事情是:

Uno k = u;
是一个(复制-初始化,它从
Uno
对象
u
复制构造
Uno
对象
k
。复制构造意味着调用复制构造函数(在本例中由编译器隐式生成),而不是默认构造函数

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

另外请注意,上述声明一般不等同于此:

Uno k;
k = u;

在最后一个片段中,表达式<代码> k= u是赋值,不是初始化。虽然两个构造都使用了= /Cuth>符号,但不应该让它迷惑你。

< P>这是因为你的类没有拷贝构造函数。如果没有复制构造函数,那么C++调用默认的构造函数。显然这不是HAV。E CUT< P>这是因为你的类没有复制构造函数。如果没有创建复制构造函数,那么C++调用默认的构造函数。显然,它没有CUT

暂时放在我的脚注上…除非你明确地告诉编译器否则,默认情况下,你总是有复制构造函数:

Uno(const Uno & other);
Uno();
和赋值运算符:

Uno & operator=(const Uno & other);
无论您是否要求。如果您没有定义任何其他构造函数,您也会得到默认构造函数:

Uno(const Uno & other);
Uno();
由于您已经定义了无参数构造函数,因此将使用您的构造函数而不是最后一个默认构造函数

定义变量时:

Uno u;
构造函数用于初始化对象实例。执行赋值时:

Uno k=u;
使用赋值运算符

您可能会问,我如何阻止复制或分配对象?将它们声明为私有,而不要实现它们:

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

暂时戴上我的学究帽……除非您明确告诉编译器,否则,默认情况下,您始终拥有复制构造函数:

Uno(const Uno & other);
Uno();
和赋值运算符:

Uno & operator=(const Uno & other);
无论您是否要求。如果您没有定义任何其他构造函数,您也会得到默认构造函数:

Uno(const Uno & other);
Uno();
由于您已经定义了无参数构造函数,因此将使用您的构造函数而不是最后一个默认构造函数

定义变量时:

Uno u;
构造函数用于初始化对象实例。执行赋值时:

Uno k=u;
使用赋值运算符

您可能会问,我如何阻止复制或分配对象?将它们声明为私有,而不要实现它们:

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

这不清楚。你的构造函数被调用了一次还是两次?这不清楚。你的构造函数在吗