我不明白为什么我会这样做:
struct S {
int a;
S(int aa) : a(aa) {}
S() = default;
};
为什么不直接说:
S() {} // instead of S() = default;
为什么要为此引入新语法?
原文由 user3111311 发布,翻译遵循 CC BY-SA 4.0 许可协议
我不明白为什么我会这样做:
struct S {
int a;
S(int aa) : a(aa) {}
S() = default;
};
为什么不直接说:
S() {} // instead of S() = default;
为什么要为此引入新语法?
原文由 user3111311 发布,翻译遵循 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 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
默认的默认构造函数被明确定义为与没有初始化列表和空复合语句的用户定义的默认构造函数相同。
但是,虽然两个构造函数的行为相同,但提供空实现确实会影响类的某些属性。提供用户定义的构造函数,即使它什么都不做,也会使类型不是 _聚合_,也不是 琐碎 的。如果您希望您的类是聚合类型或普通类型(或通过传递性,POD 类型),那么您需要使用
= default
。展示:
此外,显式默认构造函数将使其成为
constexpr
如果隐式构造函数本来是并且还将给它与隐式构造函数相同的异常规范。在您给出的情况下,隐式构造函数不会是constexpr
(因为它会使数据成员未初始化)并且它也会有一个空的异常规范,所以没有区别。但是是的,在一般情况下,您可以手动指定constexpr
和异常规范以匹配隐式构造函数。使用
= default
确实带来了一些一致性,因为它也可以与复制/移动构造函数和析构函数一起使用。例如,一个空的复制构造函数与默认的复制构造函数(它将执行其成员的成员复制)不同。对每个特殊成员函数统一使用= default
(或= delete
)语法,通过明确说明您的意图,使您的代码更易于阅读。