复制构造函数/赋值运算符

时间:2014-10-07 20:39:59

标签: c++ copy-constructor accelerated-c++

我正在学习Accelerated C ++中的自动转换,作者声明当你有一个表单声明时总是调用复制构造函数

myClass myVar = 24;

另外,他说当你有表格的陈述时

myClass myVar;
myVar = 24;

实际发生的是调用以整数作为参数的myClass构造函数来创建myClass类型的未命名临时变量,然后调用赋值运算符。我相信这本书写于2000年。我的问题是这些说法是否仍然属实。我了解了移动构造函数并将赋值操作移动到其他地方,我想知道是否调用了这些操作而不是赋值操作符/复制构造函数。

感谢您的时间。对此,我真的非常感激。

1 个答案:

答案 0 :(得分:2)

  

...作者声明,当你有一个表单声明

时,总是会调用复制构造函数
myClass myVar = 24;

<强>错误

你的书是在C ++ 11成为新标准之前编写的,所以它没有提到移动语义和可能会调用 move-constructor 的可能性。而且,它没有谈论 copy-elision 。是的,确实可以调用调用的复制构造函数,但由于名为copy-elison的优化,允许编译器从复制/移动构造函数中删除调用。这是允许的,即使它可能会影响程序的行为,但请注意,这不是保证在每个编译器上发生。

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

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

  

§8.5/ 15初始化程序

     
    

形式出现的初始化
T x = a;
         

以及     参数传递,函数返回,抛出异常(15.1),     处理异常(15.3),并聚合成员初始化     (8.5.1)称为复制初始化。 [注意:复制初始化可能     调用移动(12.8)。 - 结束说明]

  

假设没有发生copy-elision,编译器将构造一个类的临时实例,以便转换为指定的类型。然后,它将使用copy-constructor或move-constructor从此临时文件复制或移动构造myVar。移动构造函数优先于rvalues的复制构造函数,并且只有在类具有可访问的移动构造函数时才会调用它。否则调用复制构造函数。

如果没有发生copy-elision,编译器将初始化myVar,就像它是从右侧复制构造一样。这符合as-if rule,它指出编译器可以执行优化,因为它不会影响程序的可观察行为

  

另外,他说当你有表格的陈述时

myClass myVar;
myVar = 24;
     

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

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

开始
  

§12.3转化次数

     
    

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

  

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