在C ++中,假定C是带有构造函数的类。当通过以下方式定义c的实例C

C c = C(args);


=是否调用将C(args)返回(作为对构造函数的调用)作为参数的副本构造函数?

还是=不调用副本构造函数,而是将名称c关联到C(args)的返回对象?

谢谢。

最佳答案

可以调用copy构造函数,但也可以在C ++ 14和更早的版本中对其进行优化(又称“复制删除”)。但是在C ++ 17中,可以保证省略。

C ++ 17与以前的标准之间的区别是,即使C ++ 14及更早版本中没有复制ctor调用,它也必须存在,即使未调用也是如此。这是一个例子:

struct C {
    C(int) { }
    C(const C&) = delete;
};

int main()
{
    C c = C(1);
}


在C ++ 17中,它将进行编译。在C ++ 14和更早的版本中,它不会。即使编译器也可能在C ++ 14中取消了副本ctor,也不允许它接受代码。由于C ++ 17保证了省略,因此不需要复制ctor。

请注意,这与移动语义无关。 C c = C(1)不会将临时文件移到c中。我们也可以删除move构造函数:

struct C {
    C(int) { }
    C(C&&) = delete;
    C(const C&) = delete;
};


而且它仍然可以在C ++ 17中编译。这是省略,不是移动操作。

这里也没有作业。在声明中,不以赋值运算符开头。但是我们可能会偏执,并且也可以删除它们(分配操作符和移动分配操作符):

struct C {
    C(int) { }
    C(C&&) = delete;
    C(const C&) = delete;
    C& operator=(const C&) = delete;
    C& operator=(C&&) = delete;
};


而且它仍将在C ++ 17中编译。

关于c++ - C c = C(args);中的=是否调用复制构造函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47114487/

10-11 19:10
查看更多