嗨,我想了解构造函数在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有默认构造函数(我们显式定义的)。我还知道,如果我们不为一个类提供任何构造函数,那么它将自动生成一个默认构造函数。因此,根据这个,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上。为什么这两个结构体之间有区别呢?
因此,应该根据此生成默认构造函数自动执行结构体A
…当需要生成时。
如果你真的尝试创建它的一个实例,你会发现它也不能工作。如果您试图声明A
的实例,编译器将尝试生成一个,并且失败。
在B
的情况下,您定义了一个显式构造函数,并且由于它无法显式构造它的b_member
,编译器尝试默认构造它,并且失败了,因为它没有默认构造函数。
如cppreference所述,声明了A
的默认构造函数。
3隐式声明的默认构造函数
如果没有为类类型(结构、类或联合)提供任何类型的用户声明构造函数,编译器将始终将默认构造函数声明为其类的内联公共成员。
但是在你的小例子中,它没有定义,因为它从来没有被调用/需要。
4隐式定义的默认构造函数
如果隐式声明的默认构造函数未定义为删除,则在不使用或需要用于常量求值(c++ 11起)时,由编译器定义(即生成并编译函数体),
如果您尝试调用它(只是添加一个A a;
),那么您将得到您期望的错误。