在`C c = C(args)中``````调用复制构造函数?

时间:2017-11-04 19:04:19

标签: c++

在C ++中,假设C是一个带有构造函数的类。通过

定义c的实例C
C c = C(args);

=是否会调用一个复制构造函数,它将C(args)的返回作为参数,对构造函数的调用?

或者=是否不调用复制构造函数,而是将名称cC(args)的返回对象相关联?

感谢。

1 个答案:

答案 0 :(得分:4)

可以调用复制构造函数,但也可以在C ++ 14及更早版本中对其进行优化(也称为“复制省略”)。但是在C ++ 17中,保证了这一点。

C ++ 17和先前标准之间的区别在于即使复制ctor调用在C ++ 14及更早版本中被省略,它仍然必须存在,即使它没有被调用。这是一个例子:

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

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

在C ++ 17中,这将编译。在C ++ 14及更早版本中,它不会。尽管编译器也可能在C ++ 14中忽略了复制ctor,但是不允许它接受代码。由于C ++ 17保证了省略,因此不需要存在复制文件。

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

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中编译。