C 11 中的新语法“= default”

新手上路,请多包涵

我不明白为什么我会这样做:

 struct S {
    int a;
    S(int aa) : a(aa) {}
    S() = default;
};

为什么不直接说:

 S() {} // instead of S() = default;

为什么要为此引入新语法?

原文由 user3111311 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 489
2 个回答

默认的默认构造函数被明确定义为与没有初始化列表和空复合语句的用户定义的默认构造函数相同。

§12.16 [class.ctor] 默认构造函数被默认且未定义为已删除,当它被用于创建其类类型的对象或在其第一次声明后显式默认时,它被隐式定义。隐式定义的默认构造函数执行类的一组初始化,这些初始化将由用户编写的该类的默认构造函数执行,没有 ctor-initializer (12.6.2) 和空的复合语句。 […]

但是,虽然两个构造函数的行为相同,但提供空实现确实会影响类的某些属性。提供用户定义的构造函数,即使它什么都不做,也会使类型不是 _聚合_,也不是 琐碎 的。如果您希望您的类是聚合类型或普通类型(或通过传递性,POD 类型),那么您需要使用 = default

§8.5.11 [dcl.init.aggr] 聚合是没有用户提供的构造函数的数组或类,[和…]

§12.15 [class.ctor] 如果默认构造函数不是用户提供的并且 […]

§9/6 [类] 普通类是具有普通默认构造函数和 […]

展示:

 #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 )语法,通过明确说明您的意图,使您的代码更易于阅读。

原文由 Joseph Mansfield 发布,翻译遵循 CC BY-SA 4.0 许可协议

我有一个例子可以显示差异:

 #include <iostream>

using namespace std;
class A
{
public:
    int x;
    A(){}
};

class B
{
public:
    int x;
    B()=default;
};

int main()
{
    int x = 5;
    new(&x)A(); // Call for empty constructor, which does nothing
    cout << x << endl;
    new(&x)B; // Call for default constructor
    cout << x << endl;
    new(&x)B(); // Call for default constructor + Value initialization
    cout << x << endl;
    return 0;
}

输出:

 5
5
0

正如我们所见,对空 A() 构造函数的调用不会初始化成员,而 B() 会这样做。

原文由 Slavenskij 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏