2014-10-01 94 views
14

我在这里检讨的拷贝构造函数的cppreference页: http://en.cppreference.com/w/cpp/language/copy_constructor隐式声明和隐式定义的拷贝构造函数之间的区别是什么?

我读过关于隐式声明的拷贝构造函数和隐式定义的拷贝构造函数的2节好几次,但我还是不明白区别。不会隐式声明但未定义的构造函数会导致链接器问题?

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

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

回答

11

这在第12条开始澄清在一份报告中的标准:

[注:程序不 时不 实施将隐含了一些类的类型声明这些成员函数明确地声明它们。如果它们是odr-used的(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

非常棒的解释。我希望看到更多隐式声明与其他已删除/隐式定义/平凡情况相结合的不同场景的例子。 – 2014-10-01 20:09:28

3

如果存在隐式声明的拷贝构造函数,则始终将其定义为。为它定义的选项有:

  • 删除
  • 琐碎
  • 隐式定义的

如果程序试图使用被定义为然后删除一个构造程序是非法的构造(即你得到一个编译器错误)。在其他情况下,函数被调用。

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

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

可微复制之间的区别总是在那里,但它没有说得很清楚;你从关于POD的规则中推断出它允许使用memcpy来复制对象。

正如Brian指出的那样,如果要求定义为更准确。编译器从不隐式声明一个函数,然后生成一个链接错误。但是,如果函数定义不是成功构建可执行文件所必需的,那么实际上并不会形成定义。

+0

也许我错了,但声明是定义的一个子集。换句话说,如果定义了某些东西,它也会被声明。但是,如果声明了某些内容并不意味着它已被定义(因此我们会说它已被定义) – 2014-10-01 20:04:15

+1

@ void.pointer您正在讨论用户提供的语法结构。这是谈论编译器生成的构造函数。编译器从不隐式地声明一个没有定义它的函数(就像Brian指出的那样,编译器如果没有真正调用编译器就不会生成定义)。 – 2014-10-01 20:06:21

相关问题