为什么在这里调用复制构造函数而不是普通的构造函数和重载的赋值运算符?

Ane*_*pal 4 c++ copy-constructor

可能重复:
复制初始化和直接初始化之间的C++是否存在差异?
复制构造函数和赋值运算符

我有一个C类,我已经重载了Normal,复制构造函数和赋值运算符来打印所调用的内容的痕迹.

我编写了以下代码来测试什么时候被调用?

C c1;                --> Normal Constuctor .. // understood Fine

C c2;
c2 = c1;             --> Normal constructor + assignment operator .. //understood Fine

C * c3 = new C(C1)   --> Copy constructor  // Understood Fine

C c4 = c1          --> copy constructor // Not Able to understand
Run Code Online (Sandbox Code Playgroud)

这似乎让我感到困惑,因为在这段代码中虽然我在声明时初始化,但它是通过赋值运算符而不是复制构造函数.我理解错了吗?

iam*_*ind 15

因为C c4 = c1;语法上在语义上等同于:

C c4(c1);
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,两者都会调用复制构造函数.然而,"复制初始化"(第一语法)和"直接初始化"(第二语法)之间存在细微差别.看看这个答案.

注意:在"外行人的术语"中,c4构造一个变量(此处),直到遇到第一个;(或,多个对象); 直到那时一切都是一种或另一种类型的构造函数.

在这种情况下C c4 = c1;,编译器不必检查最烦恼的解析.
但是,可以C c4 = c1;通过声明复制构造函数来禁用某种语法explicit.就此而言,任何构造函数都可以显式化,您可以防止=在构造中签名.

  • 我对这个答案有几个问题.第一个是纯粹的语言学:`C c4 = c1;`显然_not_句法上等同于`C c4(c1);`.你可能想说语义等价,只有初始化表达式(在这种情况下为`c1`)与新对象具有相同的类型时才是真的.最后,`c4`完全构造在声明符的末尾,如果你在同一个语句中定义了两个变量,它可能在`;`之前:`C c4 = c1,c5 = c4;`.(不好的做法,恕我直言,但完全合法.) (3认同)

Alo*_*ave 8

C c4 = c1;
Run Code Online (Sandbox Code Playgroud)

复制初始化.

如果通过查找合适的转换函数然后使用创建的实例进行复制来构建新实例,它会尝试转换c1为某种类型.CCC

但请注意,

C c4(c1);
Run Code Online (Sandbox Code Playgroud)

直接初始化

值得注意的是,复制初始化和直接初始化之间存在差异,它们并不相同!

为什么C c4 = c1;在语法上等同于C c4(C1)而不是C C4; c4 = c1;为什么这样做?
首先,复制初始化和直接初始化是不一样的.
至于为什么没有调用赋值运算符的基本原理,只有当一个对象分配两个完全形成的对象时才会进行赋值.

的情况下:

C c4 = c1;
Run Code Online (Sandbox Code Playgroud)

c1是一个完全构造的对象,c4但并不是全部存在,当这种情况出现并=存在时,它并不真正意味着赋值,但它意味着初始化.
所以基本上,这里发生的是Initialization而不是Assignment,C++ Standard定义了如何进行初始化的具体规则.