子类是否需要默认构造函数?

Does a subclass need a default constructor?

我现在正在学习继承,有一件事我还没有找到可靠的答案。如果我有三个 classes,一个是 super,两个 subclass,如果它们继承相同的字段,我的 subclasses 是否需要默认构造函数? Class b 没有默认构造函数,因为它从 A 继承了它的字段,而 class c 有不同的字段,因此它需要自己的默认构造函数。

class A {
  
    private:
        int a;
        int b;
    
    public:
        A();
        A(int, int);
    
};

class B: public A {
  
    public:
        B(int, int);
    
};

class C : public A {
  
    private:
        int c;
    
    public:
        C();
        C(int, int);
    
};

不胜感激。

如果您希望调用代码能够使用默认构造函数并创建 class 的实例而不向其传递额外的参数,则 class 应该具有默认构造函数。 B 不会因为 B 没有添加额外的成员变量而自动获取 A 的默认构造函数。

B 不会因为 A 有默认构造函数而 B 没有任何新变量而自动拥有默认构造函数。如果你想转发 A 的默认构造函数,你可以使用 using declaration 这样做:

class A {
  
    private:
        int a;
        int b;
    
    public:
        A();
        A(int, int);
    
};

class B: public A {
  
    public:
        using A::A; // All of A's constructors are now publically usable as B constructors
    
};

请注意,我删除了声明 B(int, int);,因为 using 声明将 两个 构造函数从 A 向前推进。如果您希望 B(int, int); 做一些不同于 A(int, int); 的事情,您可以在 using 声明旁边声明 B(int, int);,更多派生的构造函数将隐藏继承的构造函数。

If [irrelevant], would my subclasses need a default constructor if [irrelevant]?

这取决于您的 subclasses 的使用方式。如果 - 并且仅当 - 您需要在不提供构造参数的情况下构造 class 的实例,那么 class 需要一个默认构造函数。您是否需要显式定义(或通过 using 转发)默认构造函数取决于是否定义了其他构造函数,以及该构造函数是否有一些重要的事情要做。这个主题应该在继承之前就已经讨论过了。

但是,当继承进入画面时,有一个新的警告。因为我不知道你是否使用 member initialization lists, I recommend reading 。如果您不使用成员初始化列表,您派生的 classes 将在没有构造参数的情况下构造它们的基。但是,请注意,通常最好使用初始化列表而不是添加默认构造函数来解决这种情况。

Class b doesn't have a default constructor because it inherits its fields from A,

不,class B 没有默认构造函数,因为它定义了一个非默认构造函数。非默认构造函数阻止编译器提供默认构造函数。如果您的代码成功编译,可以得出结论 B 不需要默认构造函数。

where as class c has different fields, therefore it would need its own default constructor.

class 是否有字段与“需要”无关。 (字段可能更有可能显式默认构造函数是合适的,因为可能有数据要初始化,但它们的存在并不表示需要。)