初始化基类成员 (c++) 的首选方法

Preferred way to initialize base class members (c++)

本文关键字:方法 c++ 基类 成员 初始化      更新时间:2023-10-16

我有一个基类:

class Base {
protected:
int m_a;
virtual void foo() = 0;
}

和派生类

class Derived : public Base {
public:
Derived(int a);
}

基类是抽象的,因此只能创建派生类。 如何更好地实现派生的 Ctor?

Derived::Derived(int a) : Base(a) {}
Base::Base(int a) : m_a(a) {}

Derived::Derived(int a) { m_a = a;}
Base::Base(){}

从 Base 构造函数中删除成员是否更好,因为它不能单独创建,或者将其保留在 Base 构造函数上以保留他的赋值?

您的第一个解决方案 - 为基类提供一个显式构造函数 - 最好作为常规模式:

  • 它避免了从 Base 继承的其他类忘记初始化m_a。相反,类的签名指示需要初始化。

  • 如果多个类从 base 继承,并且初始化更复杂(例如范围检查(,则此代码和策略不会分布在多个派生类上

  • 如果m_a是不可变的,则需要构造函数初始化

  • 派生类可能有多个 CTor,需要忘记的地方更多

唯一的缺点:多打字一点 - 只要你不计算额外的"我今天有点懒,所以不要忘记在所有派生类构造函数中初始化m_a">

正如评论中提到的,"签名宣布要求"足以使其成为默认模式,因此"另一种方式需要使m_a受到保护"。

我更喜欢:

Derived::Derived(int a) : Base(a) {}
Base::Base(int a) : m_a(a) {}

通过这种方式,您可以使您的代码更加封装,并且Base成员关心其初始化列表,则基类构造函数中可以根据m_a而有更多的初始化逻辑,而不仅仅是启动m_a。在这种情况下,您将初始值传递给基构造函数,然后他的构造函数中的派生类已初始化基类的构造函数。

您应该尝试将 init 值传递给您的Base类,假设您有 5 个Derived类,您需要在所有派生的 ctors 上初始化基类。