我不明白我为什么要这样做:
struct S {
int a;
S(int aa) : a(aa) {}
S() = default;
};
为什么不直接说:
S() {} // instead of S() = default;
为什么要为此引入新语法?
最佳答案
默认的默认构造函数被明确定义为与用户定义的默认构造函数相同,没有初始化列表和空复合语句。
§12.1/6 [class.ctor] A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used to create an object of its class type or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement. [...]
但是,虽然两个构造函数的行为相同,但提供空实现确实会影响类的某些属性。给出一个用户定义的构造函数,即使它什么都不做,也使得类型不是一个聚合,也不是trivial。如果您希望您的类是聚合类型或平凡类型(或通过传递性,POD 类型),那么您需要使用 = default
。
§8.5.1/1 [dcl.init.aggr] An aggregate is an array or a class with no user-provided constructors, [and...]
§12.1/5 [class.ctor] A default constructor is trivial if it is not user-provided and [...]
§9/6 [class] A trivial class is a class that has a trivial default constructor and [...]
演示:
#include <type_traits>
struct X {
X() = default;
};
struct Y {
Y() { };
};
int main() {
static_assert(std::is_trivial<X>::value, "X should be trivial");
static_assert(std::is_pod<X>::value, "X should be POD");
static_assert(!std::is_trivial<Y>::value, "Y should not be trivial");
static_assert(!std::is_pod<Y>::value, "Y should not be POD");
}
此外,如果隐式构造函数本来是,显式默认构造函数将使其成为 constexpr
,并且还将为其提供与隐式构造函数相同的异常规范。在您给出的情况下,隐式构造函数不会是 constexpr
(因为它会使数据成员未初始化)并且它也会有一个空的异常规范,所以没有区别。但是是的,在一般情况下,您可以手动指定 constexpr
和异常规范以匹配隐式构造函数。
使用 = default
确实带来了一些统一性,因为它也可以与复制/移动构造函数和析构函数一起使用。例如,一个空的复制构造函数与默认的复制构造函数(它将执行其成员的成员复制)不同。对这些特殊成员函数中的每一个统一使用 = default
(或 = delete
)语法,通过明确说明您的意图,使您的代码更易于阅读。
关于c++ - C++11 中的新语法 "= default",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20828907/