4

可能重复:
复制初始化和直接初始化在 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

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

4

3 回答 3

15

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

C c4(c1);

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

注意:在“外行的术语”中,构造一个变量(这里c4)直到遇到第一个;(或,' 对于多个对象);到那时,一切都是一种或另一种类型的构造函数。

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

于 2012-05-15T06:45:25.097 回答
8
C c4 = c1;

复制初始化

如果它已经不是该类型,它会尝试通过找到合适的转换函数来转换c1为该C类型,然后使用创建的C实例来复制构造一个新C实例。

请注意,虽然,

C c4(c1);

直接初始化

重要的是要注意复制初始化和直接初始化之间有区别,它们是不一样的!

为什么C c4 = c1;在语法上等同于C c4(C1)而不是C C4; c4 = c1;为什么它是这样制作的?
首先,复制初始化和直接初始化是不一样的。
至于为什么不调用赋值运算符的基本原理,只有在将两个完全形成的对象相互赋值时才会发生赋值。

的情况下:

C c4 = c1;

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

于 2012-05-15T06:49:28.743 回答
1

因为没有赋值运算符:

C c4 = c1;

与逗号一样,等号可以是运算符或标点符号。在表达式中,它始终是一个运算符,但在上面,初始化表达式很简单c1;符号是=标点符号,表示要使用复制初始化,而不是直接初始化。(直接初始化将是

C c4( c1 );

并且,恕我直言,通常更可取。但是,在初始化表达式与新对象具有相同类型的情况下,没有区别。)

于 2012-05-15T07:47:36.870 回答