我对C ++中的默认构造函数有疑问。例如,在A类中,使用此默认构造函数A(){};
或A() = default;
有什么区别?它们之间的一般区别是什么?
提前谢谢!
答案 0 :(得分:5)
在第一个声明中定义为默认的构造函数被认为不是用户提供的。这基本上就像隐含在C ++ 03中一样。在聚合类中允许这样的构造函数声明。
struct ag {
ag() = default;
int a;
double b;
};
struct nag {
nag() {}
int a;
double b;
};
ag a = { 5, 12. }; // OK
nag na = { 5, 12. }; // error: not an aggregate and no appropriate constructor
此规则仅适用于班级中出现= default
的情况。鉴于此类定义:
struct nag {
nag();
int a;
double b;
};
然后这些构造函数定义确实完全等效:
nag::nag() {} // 1
nag::nag() = default; // 2
explicit
默认构造函数通常禁用空副本列表初始化语法(= {}
)和{}
作为参数或return
值。聚合中的显式默认和explicit
默认构造函数容易混淆地遵守此规则,因为聚合初始化具有比构造函数初始化更高的优先级。这提供了一种检测类是否为聚合的方法,但您可能不应这样做。
struct sadistic {
explicit sadistic() = default;
// members
};
sadistic se = {}; // OK only if sadistic has no virtual functions, etc.
答案 1 :(得分:1)
默认构造函数的行为对于每个12.1p6的A() {}
和A() = default;
是相同的:
隐式定义的默认构造函数执行该类的初始化集合,该初始化集合将由该用户编写的默认构造函数执行,该类没有ctor-initializer(12.6.2)和空复合语句。
区别在于:
constexpr
(显式默认的构造函数是constexpr
,如果它是有效的),最后一点:
#include <iostream>
struct A { int i; A() = default; };
struct B { int j; B() {} };
int main() {
int i = 42, j = 42;
new (&i) A();
new (&j) B();
std::cout << i << std::endl; // 0
std::cout << j << std::endl; // 42
}
所以你可能想要编写一个用户提供的非默认默认构造函数,例如,如果你的类具有零初始化(例如一个大数组)会很昂贵的琐碎成员,但是这是一个非常小众的案例。
答案 2 :(得分:-1)
没有太多差异:
旧语法(请注意,不需要;
):
A() {}
从C ++的第一天开始就可用。它将默认构造每个基类和成员变量。
新的C ++ 11语法:
A() = default;
完全相同,但它是默认的,所以你(或编译器)不必检查大括号是否真的是空的。
请注意,如果某个类没有声明的构造函数,编译器将为您添加一个。
CORRECTION :如果删除了默认构造函数,则存在差异,即类隐式默认构造函数无效。在这种情况下,{}
是语法错误,而=default
就像删除的定义:
struct S
{
int &r; //non default constructible
S() {} //error: uninitialized reference S::r;
S() = default; //ok: deleted constructor
S() = delete; //also ok (but not both!)
};