编译器是否每次都实例化默认和复制构造函数以及复制赋值运算符?

时间:2015-06-04 04:21:45

标签: c++ constructor

问题几乎在标题中。考虑简单程序中的空类,比如说

struct A{ };

int main(){ }

编译器是否必须实例化所有这些函数或者它的实现是否已定义?我的意思是,在仅调用它们的情况下对这些函数进行intstatiate(我认为,编译器可能会确定它们是否以某种方式被调用)。

2 个答案:

答案 0 :(得分:4)

隐式声明特殊成员函数,除非它们是odr-used,在这种情况下它们将被隐式定义。

来自N3337,§12/ 1 [特别]

  

默认构造函数(12.1),复制构造函数和复制赋值运算符(12.8),移动构造函数和移动赋值运算符(12.8)以及析构函数(12.4)是特殊成员函数。 [注意:   当程序没有显式声明它们时,实现将隐式声明某些类类型的这些成员函数。如果它们使用得很多,那么实现将隐式定义它们(3.2)。见12.1,12.4和12.8。 -end note ]

答案 1 :(得分:1)

在创建对象时,如果编译器发现没有为您的类定义构造函数,它会为您生成一个构造函数。构造函数是初始化类的数据成员所需的函数(并执行其他关键操作,如设置VTABLE和定义VPTR - 如果您的类声明至少有一个虚函数)。

在通过复制构造函数或复制赋值运算符创建新对象时(即,从现有对象创建对象时),编译器生成的复制构造函数将执行仅仅浅层复制(纯文本按位复制) )数据成员的值(可能导致悬空指针情况 - 如果您的类有一个指针数据成员,并且您碰巧创建了多个指向您的类对象的引用/指针,然后通过一个对象被销毁其中 - 由于某些故意/无意的原因,如果你访问那些悬空指针导致崩溃)。因此,它始终建议您定义自己的复制构造函数和复制赋值运算符,并执行“深度复制”操作。你的类有一个"指针数据成员"。