什么是 C++ 中的非平凡构造函数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3899223/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is a non-trivial constructor in C++?
提问by AnT
I was reading this http://en.wikipedia.org/wiki/C%2B%2B0x#Modification_to_the_definition_of_plain_old_data
我正在阅读这个http://en.wikipedia.org/wiki/C%2B%2B0x#Modification_to_the_definition_of_plain_old_data
It mentions trivial default constructor, trivial copy constructor, copy assignment operator, trivial destructor. What is trivial and not trivial?
它提到了平凡的默认构造函数、平凡的复制构造函数、复制赋值运算符、平凡的析构函数。什么是微不足道的和不微不足道的?
回答by AnT
In simple words a "trivial" special member function literally means a member function that does its job in a very straightforward manner. The "straightforward manner" means different thing for different kinds of special member functions.
简单来说,“平凡”的特殊成员函数的字面意思是一个以非常直接的方式完成工作的成员函数。“直截了当”对于不同类型的特殊成员函数意味着不同的东西。
For a default constructor and destructor being "trivial" means literally "do nothing at all". For copy-constructor and copy-assignment operator, being "trivial" means literally "be equivalent to simple raw memory copying" (like copy with memcpy
).
对于默认构造函数和析构函数,“微不足道”的字面意思是“什么都不做”。对于复制构造函数和复制赋值运算符,“平凡”的字面意思是“等同于简单的原始内存复制”(如 copy with memcpy
)。
If you define a constructor yourself, it is considered non-trivial, even if it doesn't do anything, so a trivial constructor must be implicitly defined by the compiler.
如果你自己定义一个构造函数,它被认为是非平凡的,即使它什么都不做,所以一个平凡的构造函数必须由编译器隐式定义。
In order for a special member function to satisfy the above requirements, the class must have a very simplistic structure, it must not require any hidden initializations when an object is being created or destroyed, or any hidden additional internal manipulations when it is being copied.
为了使特殊的成员函数满足上述要求,类必须具有非常简单的结构,在创建或销毁对象时不得进行任何隐藏的初始化,或在复制对象时进行任何隐藏的附加内部操作。
For example, if class has virtual functions, it will require some extra hidden initializations when objects of this class are being created (initialize virtual method table and such), so the constructor for this class will not qualify as trivial.
例如,如果类有虚函数,在创建这个类的对象时需要一些额外的隐藏初始化(初始化虚方法表等),所以这个类的构造函数不会被认为是微不足道的。
For another example, if a class has virtual base classes, then each object of this class might contain hidden pointers that point to other parts of the very same object. Such a self-referential object cannot be copied by a simple raw memory copy routine (like memcpy
). Extra manipulations will be necessary to properly re-initialize the hidden pointers in the copy. For this reason the copy constructor and copy-assignment operator for this class will not qualify as trivial.
再举一个例子,如果一个类有虚拟基类,那么这个类的每个对象都可能包含指向同一对象其他部分的隐藏指针。这种自引用对象无法通过简单的原始内存复制例程(如memcpy
)复制。需要额外的操作来正确地重新初始化副本中的隐藏指针。出于这个原因,此类的复制构造函数和复制赋值运算符不会被视为微不足道的。
For obvious reasons, this requirement is recursive: all subobjects of the class (bases and non-static members) must also have trivial constructors.
出于显而易见的原因,这个要求是递归的:类的所有子对象(基类和非静态成员)也必须有平凡的构造函数。
回答by Prasoon Saurav
A constructor of a class A is trivialif all the following are true:
如果以下所有条件都为真,则类 A 的构造函数是微不足道的:
- It is implicitly defined (compiler synthesized)
- A has no virtual functions and no virtual base classes
- All the direct base classes of A have trivial constructors
- The classes of all the nonstatic data members of A have trivial constructors
- 它是隐式定义的(编译器合成)
- A 没有虚函数和虚基类
- A 的所有直接基类都有平凡的构造函数
- A 的所有非静态数据成员的类都有平凡的构造函数
回答by jogojapan
There are correct answers already, but here is the quote from the Standard (which I was looking for when I came across this post):
已经有正确的答案,但这里引用了标准(当我看到这篇文章时我正在寻找):
(§12.1/5) A default constructor is trivial if it is not user-provided and if:
— its class has no virtual functions (10.3) and no virtual base classes (10.1), and
— no non-static data member of its class has a brace-or-equal-initializer, and
— all the direct base classes of its class have trivial default constructors, and
— for all the non-static data members of its class that are of class type (or array thereof), each such class has a trivial default constructor.
(第 12.1/5 节)如果不是用户提供的默认构造函数是微不足道的,并且如果:
— 它的类没有虚拟函数 (10.3) 和虚拟基类 (10.1),并且
— 它的类没有非静态数据成员类有一个大括号或等号初始化器,并且
——它的类的所有直接基类都有平凡的默认构造函数,并且
——对于它的类的所有非静态数据成员,它们是类类型(或其数组),每个这样的类都有一个简单的默认构造函数。
This is from C++11. C++03 lacks the second item and uses the phrase implicitly declaredinstead of not user-provided. It is otherwise identical.
这是来自 C++11。C++03 缺少第二项并使用隐式声明的短语而不是not user-provided。否则是相同的。
Note that this specification only covers trivial default constructors. The word attribute trivialcan also be used in different contexts, e.g. copy constructors.
请注意,此规范仅涵盖琐碎的默认构造函数。单词attribute trivial也可以用在不同的上下文中,例如复制构造函数。