隐式声明和隐式定义的复制构造函数之间有什么区别?

时间:2014-10-01 19:53:07

标签: c++ copy-constructor

我正在审核复制构造函数的cppreference页面: http://en.cppreference.com/w/cpp/language/copy_constructor

我已经阅读了有关隐式声明的复制构造函数和隐式定义的复制构造函数的2个部分,但我仍然不了解这种区别。隐式声明但未定义的构造函数会导致链接器问题吗?

规则非常复杂。我不记得在C ++ 03中有区别:你有一个编译器生成的拷贝构造函数,或者你没有。

有人可以解释(用简单的话说)这两个类别之间的区别/差异是什么?

2 个答案:

答案 0 :(得分:11)

第12条开头的标准说明中阐明了这一点:

  

[注意:   实现将在程序执行时隐式声明某些类类型的这些成员函数   没有明确声明它们。如果它们使用得很多,那么实现将隐式定义它们(3.2)。    见12.1,12.4和12.8。 - 结束记录]

C ++ 14(N3936)的规范性参考文献是12.1 / 5,12.4 / 6,12.8 / 13,12.8 / 26。在每种情况下,如果默认并且未定义为已删除,则默认定义相应的特殊成员函数,并使用odr-used或显式默认。如果我们有像

这样的东西
struct Foo {};

并且没有创建类型Foo的对象,所有六个特殊成员函数(默认构造函数,析构函数,复制构造函数,移动构造函数,复制赋值运算符,移动赋值运算符)都隐式声明为默认值,但不是定义,因为它们没有使用。

答案 1 :(得分:3)

如果存在隐式声明的复制构造函数,则始终定义 1 。其定义的选项是:

  • 删除
  • 琐碎
  • 隐式定义

如果程序试图使用定义为已删除的构造函数,则程序格式错误(即编译器出错)。在其他情况下,调用该函数。

您链接的页面描述了上述三种选项中的每一种情况。

C ++ 11添加了delete d函数的概念,因为当你想明确地使一个类成为不可复制的(等)时。您将其copy-constructor定义为已删除,然后如果有人试图复制您的对象,则编译器会生成错误。

平易可复制的之间的区别总是存在,但是没有明确说明;您从有关POD的规则中推断出允许使用memcpy来复制对象的情况。

1 正如Brian指出的那样,更准确地说,如果需要,则被定义。编译器从不隐式声明函数,然后生成链接错误。但是,如果不需要函数定义来成功构建可执行文件,那么它实际上不会形成定义。