0

I am learning about automatic conversions in Accelerated C++, and the author states that the copy constructor is always called when you have a statement of the form

myClass myVar = 24;

Additionally he states that when you have statements of the form

myClass myVar;
myVar = 24;

what actually happens is that the myClass constructor that takes an integer as an argument is called to create an unnamed temporary variable of the type myClass, and then the assignment operator is called. The book was written in the year 2000, I believe. My question is whether or not these claims are still true. I learned about the move constructor and move assignment operations elsewhere, and I was wondering if those were called instead of the assignment operator/copy constructor.

Thank you for your time. I really appreciate it.

4

1 回答 1

2

...作者指出,当您有表单的语句时,始终会调用复制构造函数

myClass myVar = 24;

错了

您的书是在 C++11 成为新标准之前编写的,因此它没有提到移动语义以及可能调用移动构造函数的可能性。此外,它没有谈论复制省略。是的,确实可以调用被调用的复制构造函数,但是由于称为复制elison 的优化,允许编译器从复制/移动构造函数中删除调用。这是允许的,即使它可能会影响程序的行为,但请注意,这并不能保证在每个编译器上都会发生。

如果您编写一个程序来测试这种行为,您会发现没有调用复制/移动构造函数。传递命令行参数会禁用此省略并允许来自move-constructor的调用。-fno-elide-constructors

您正在使用的初始化形式称为复制初始化

§ 8.5/15 初始化器

表单中发生的初始化

T x = a;

以及在参数传递、函数返回、抛出异常 (15.1)、处理异常 (15.3) 和聚合成员初始化 (8.5.1) 中称为复制初始化。[注意:复制初始化可能会调用移动(12.8)。——尾注]

假设没有发生复制省略,编译器将构造该类的一个临时实例,以便转换为指定的类型。然后它将myVar使用复制构造函数或移动构造函数从这个临时复制或移动构造。移动构造函数优先于右值的复制构造函数,并且仅当您的类具有可访问的移动构造函数时才会调用;否则调用复制构造函数。

如果没有发生复制省略,编译器将初始化myVar,就好像它是从右侧复制构造的一样。这符合as-if 规则,即编译器可以在不影响程序的可观察行为的情况下执行优化。

此外,他指出,当您有表格的陈述时

myClass myVar;
myVar = 24;

实际发生的myClass 是调用以整数作为参数的构造函数来创建类型为 的未命名临时变量myClass,然后调用赋值运算符。[...] 我的问题是这些说法是否仍然正确。

是的,构造函数确实参与了隐式类型转换。从最新的草案,N3797

§ 12.3 转换

类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换(第 4 条)、初始化(8.5)和显式类型转换(5.4、5.2.9)

您的作者对该部分的解释是正确的,除了移动赋值运算符将在可访问时被调用。

于 2014-10-07T21:33:25.203 回答