c++ - C++11 中的新语法 "= default"

标签 c++ c++11

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

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/

相关文章:

c++ - 是否可以将常量引用转换为指针?

c++ - 用户定义类的交换函数从未实例化?

C++根据模板参数值更改成员函数定义

c++ - 需要为c++中的以下问题设计递归算法

c++ - 将窗口设置为始终在 Windows 7 上的桌面上

c++ - 为什么一个简单的 SDL 程序在 Valgrind 中会报告内存泄漏?

c++ - 在 Qt 中正确使用 C++11 基于范围的 for 循环

c++ - TR1 是 "missing"- 我的项目配置中缺少哪个 header 或库?

c++ - 有没有办法将表示为字符串的数字转换为其二进制等价物?

c++ - 尝试访问类的字符串成员时出现段错误