C++ 我应该调用初始化列表中的基类默认构造函数吗?
案例二是否与案例一相同 对我来说,我假设在案例II中没有调用基类B的默认构造函数。然而,尽管我仍然持有这一假设,但我进行了一项测试,结果证明并非如此:C++ 我应该调用初始化列表中的基类默认构造函数吗?,c++,inheritance,constructor,C++,Inheritance,Constructor,案例二是否与案例一相同 对我来说,我假设在案例II中没有调用基类B的默认构造函数。然而,尽管我仍然持有这一假设,但我进行了一项测试,结果证明并非如此: class A : public B { ... } // case I : explicitly call the base class default constructor A::A() : B() { ... } // case II : don't call the base class default constructo
class A : public B
{
...
}
// case I : explicitly call the base class default constructor
A::A() : B()
{
...
}
// case II : don't call the base class default constructor
A::A() // : B()
{
...
}
在这两种情况下都会调用基类构造函数
下面是一篇文章的详细信息。如果基类构造函数不带任何参数,则不需要在初始化列表中明确提及它。从其他类派生的每个类都必须调用基类的构造函数。只有在完全构造所有基类之后,才能构造派生类。因此,是否调用基类的构造函数并不重要。若你们不调用,只要有一个默认的构造函数可供编译器决定,它就会被调用。否则编译器将抛出错误。为了完成学习体验并加深理解,您可以开始稍微修改一些内容。例如,当
B
没有默认构造函数时会发生什么?它甚至可以编译吗?其他像这样的轻微修改将提供一个伟大的学习经验
也就是说,根据我的经验,这样做通常更好
B constructor
A constructor
Press any key to continue . . .
因为前者更显式,它将让您思考基类初始化的实际情况。你可能会通过明确地解释事情来避免隐藏的行为 如果
B
没有用户声明的构造函数,则行为不同。比较:
A::A() { ... }
现在,w.a
和w.b
保证为零。如果不进行基类的显式初始化,则它们将具有不确定的值
您可能不知道,尽管有语法,但是上面使用的
SimpleAggregate()
并没有调用默认构造函数。它只是值初始化基类(关于什么是“值初始化”,我们在这里有几个很好的答案),没有调用默认构造函数,因为没有用户声明。我给了你一个加号,因为你建议了一些方法来提高人们对这个主题的理解。我给了+1,因为这回答了“应该…”的问题。其他大多数答案都是针对相关问题“必须……”。这是一个很大的区别。这个答案应该被接受。
A::A() : B() { ... }
A::A() { ... }
struct SimpleAggregate {
int a;
float b;
};
struct ClassWrapper : SimpleAggregate {
ClassWrapper() : SimpleAggregate() { }
};
ClassWrapper w;