C++ 声明默认构造函数是否明确禁止生成合成的构造函数?

C++ 声明默认构造函数是否明确禁止生成合成的构造函数?,c++,C++,我想知道我是否得到正确答案的一个基本问题是: 为什么案例1不起作用,但案例2起作用?(假设在main()中我们编写boob; 案例1 template <typename T> class Boo { public: Boo(); private: }; 模板 类Boo { 公众: Boo(); 私人: }; 案例2 template <typename T> class Boo { public: Boo() = default; private:

我想知道我是否得到正确答案的一个基本问题是:

为什么案例1不起作用,但案例2起作用?(假设在main()中我们编写
boob;

案例1

template <typename T>
class Boo
{
public:
    Boo();
private:
};
模板
类Boo
{
公众:
Boo();
私人:
};
案例2

template <typename T>
class Boo
{
public:
    Boo() = default;
private:
};
模板
类Boo
{
公众:
Boo()=默认值;
私人:
};
我认为案例1不起作用的原因是编译器看到我们声明了一个ctor,因此它停止生成合成的ctor。当我们声明一个类对象时,编译器找不到所需默认ctor的定义,因此这是一个编译错误

案例2之所以有效,是因为
=default
明确允许编译器为我们生成一个默认的ctor


我的推理正确吗?

我假设您在案例1中遇到一个未定义的引用链接器错误。它“不工作”的原因仅仅是因为您声明了构造函数
Boo()
,但没有定义它。如果在案例1中您编写了
Boo(){}
(用空体定义了构造函数),链接器不会抱怨

我认为案例1不起作用的原因是编译器看到我们声明了一个ctor,所以它停止生成合成的ctor

部分为true。它不会生成默认构造函数,但仍会生成副本构造函数

template <typename T>
class Boo
{
public:
    Boo() {}
private:
};
当我们声明一个类对象时,编译器找不到所需的默认构造函数的定义,因此这是一个编译错误

这将是链接器错误,而不是编译器错误

您可以通过定义构造函数轻松地解决此问题

template <typename T>
class Boo
{
public:
    Boo() {}
private:
};
模板
类Boo
{
公众:
Boo(){}
私人:
};

,可能会有帮助。至于“案例1不起作用,但案例2起作用”,请详细说明。首先,请创建一个示例向我们展示。然后告诉我们MVCE有什么问题,它如何“不起作用”非常相关:谢谢,这确实是一个链接器错误。我可以添加一个问题吗?假设在
private:
我有
std::shared_ptr data
之后,这将给我一个运行时错误。原因与第一种情况类似吗?
Boo()=default;
也给我同样的错误,我必须编写
Boo():data(std::make_shared()){}
@NicholasHumphrey,你的思路是对的。是的,如果你想以一种有意义的方式使用它,你需要初始化
数据
。@NicholasHumphrey即使你没有在构造函数中初始化
数据
,你也不应该得到运行时错误,除非你在初始化之前访问
数据
例如,使用
shared\u ptr::operator->
shared\u ptr::get()
数据
没有指向有效
向量
对象的指针时。只需在用户定义的或编译器合成的构造函数中复制
数据
就可以了,所以无论您遇到什么运行时错误,都是由于您所做的其他错误造成的。@RSahu抱歉,还有一个问题。对于前面的评论(带共享指针的),为什么编译器不可能生成合成的默认ctor?我了解到,只有当编译器无法默认初始化某些内容时,它才会抛出错误。我不知道为什么它不能使用指针/智能指针进行初始化。@NicholasHumphrey什么使你认为它不能?
shared\u ptr
是默认可构造的,所以编译器如果您允许iler生成默认构造函数,那么它肯定可以生成默认构造函数。