什么是C++中的非平凡构造函数?

64 c++ constructor

我正在读这个http://en.wikipedia.org/wiki/C%2B%2B0x#Modification_to_the_definition_of_plain_old_data

它提到了普通的默认构造函数,普通的复制构造函数,复制赋值运算符,普通的析构函数.什么是微不足道而不是微不足道的?

AnT*_*AnT 75

简单来说,"普通"特殊成员函数字面意思是以非常直接的方式完成其工作的成员函数."直截了当的方式"对于不同类型的特殊成员函数意味着不同的东西.

对于默认构造函数和析构函数是"平凡的"意味着字面上"什么都不做".对于复制构造函数和复制赋值运算符,"平凡"意味着"相当于简单的原始内存复制"(如复制memcpy).

如果你自己定义一个构造函数,它被认为是非平凡的,即使它没有做任何事情,所以编译器必须隐式定义一个简单的构造函数.

为了使特殊成员函数满足上述要求,该类必​​须具有非常简单的结构,在创建或销毁对象时不必要求任何隐藏的初始化,或者在复制时不需要任何隐藏的附加内部操作.

例如,如果类具有虚函数,则在创建此类的对象(初始化虚方法表等)时,将需要一些额外的隐藏初始化,因此此类的构造函数不符合条件.

再举一个例子,如果一个类有虚拟基类,那么这个类的每个对象可能都包含指向同一个对象的其他部分的隐藏指针.这种自引用对象不能通过简单的原始内存复制例程(如memcpy)复制.需要额外的操作才能正确地重新初始化副本中的隐藏指针.因此,此类的复制构造函数和复制赋值运算符不符合条件.

出于显而易见的原因,这个要求是递归的:类的所有子对象(基类和非静态成员)也必须具有普通的构造函数.

  • @ acidzombie24:我做了一些修改以涵盖复制成员函数.你的第二条评论对我来说并不清楚.任何用户定义的构造函数都是非平凡的,因此一旦定义它,该类就不再是POD. (2认同)
  • @ acidzombie24:声明*any*构造函数时,将禁止默认构造函数的隐式声明.所以,你的类将具有*no*默认构造函数.这就是前C++ 0x语言中的情况.在C++ 0x,AFAIK中,您可以强制编译器生成默认构造函数,这将需要使用关键字"default"的显式声明,如链接所示. (2认同)

Pra*_*rav 30

如果满足以下所有条件,则A类的构造函数是微不足道的:

  • 它是隐式定义的(编译器合成)
  • A没有虚函数,也没有虚基类
  • A的所有直接基类都有琐碎的构造函数
  • A的所有非静态数据成员的类都具有普通的构造函数

  • 抱歉,如果这听起来很愚蠢,但是它也适用于析构函数吗? (3认同)

jog*_*pan 21

已经有正确的答案,但这里是标准的引用(当我遇到这篇文章时我正在寻找):

(§12.1/ 5)如果默认构造函数不是用户提供的,并且如果:
- 它的类没有虚函数(10.3)且没有虚基类(10.1),并且
没有它的非静态数据成员,那么默认构造函数是微不足道的class有一个大括号或者相等的初始值,并且
- 它的所有直接基类都有简单的默认构造函数,而且
- 对于类的所有非静态数据成员都是类类型(或其数组),每个这样的类都有一个普通的默认构造函数.

这是来自C++ 11.C++ 03缺少第二项并使用隐式声明的短语而不是用户提供的短语.它是完全相同的.

请注意,此规范仅涵盖普通的默认构造函数.单词属性平凡也可用于不同的上下文,例如复制构造函数.