问题描述
嗨,我想了解构造函数在 C++ 中是如何工作的。为此,我使用以下示例:
class NoDefault
{
public:
NoDefault (const std::string &){}
};
struct A
{
NoDefault my_mem;
};
struct B
{
B ()
{
} // error: no initializer for b_member
NoDefault b_member;
};
这些是我已经知道的事情:我知道类 NoDefault 没有默认构造函数,而结构 B 有一个默认构造函数(我们明确定义)。我也知道,如果我们不为类提供任何构造函数,那么它会自动生成一个默认构造函数。因此,根据this,应该为struct A
自动生成默认构造函数,因此结构A和结构B现在都应该有自己的默认构造函数。现在我收到错误:
main.cpp:在构造函数‘B::B()’中: main.cpp:23:5: 错误:没有匹配的函数用于调用“NoDefault::NoDefault()” B() {} // 错误:b_member 没有初始化器
我的问题是为什么 struct A
中没有相同的错误? struct A 没有自己版本的合成默认构造函数吗?我猜在结构 B 中我们会收到错误,因为当编译器尝试默认初始化 b_member
时它不能这样做,因为类 NoDefault
没有默认构造函数并且我们没有为 b_member 使用任何初始化程序。但是同样的事情应该发生在结构体 A 上。为什么这两个结构体之间会有区别?
解决方法
所以根据这个应该生成一个默认的构造函数 自动为 struct A
...当需要生成时。
如果你真的尝试创建它的一个实例,你会发现它也不起作用。如果您尝试声明 A
的实例,编译器将尝试生成一个实例,但会失败。
在 B
的情况下,您正在定义一个显式构造函数,并且由于它未能显式构造它的 b_member
,编译器尝试对其进行默认构造函数,并且由于它没有默认构造函数。
如 cppreference 所述,A
的默认构造函数已声明。
3 隐式声明的默认构造函数
如果没有为类类型(结构、类或联合)提供任何类型的用户声明的构造函数,编译器将始终将默认构造函数声明为其类的内联公共成员。
但是在你的小例子中它没有被定义,因为它从来没有被调用/需要。
4 隐式定义的默认构造函数
如果隐式声明的默认构造函数未定义为已删除,则由编译器定义(即,生成并编译函数体)如果 odr 使用或需要用于常量求值 (C++11 起),>
如果您尝试调用它(只需添加一个 A a;
),那么您将得到您期望的错误。