简体   繁体   English

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

[英]Preferred way to initialize base class members (c++)

I have a base class: 我有一个基类:

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

And a derived class(es) 和派生类

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

The base class is abstract, so only derived classes can be created. 基类是抽象的,因此只能创建派生类。 How is the better way to implement the derived Ctor? 如何实现派生的Ctor更好的方法?

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

Or 要么

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

Is it better to remove the member from Base constructor, since it cannot be created alone, OR to keep it on the Base constructor to stay the assignment for him? 从Base构造函数中删除成员是否更好,因为它不能单独创建,或者将它保留在Base构造函数上以便为他保留赋值?

Your first solution- giving the base class an explicit constructor - is preferable as general pattern: 您的第一个解决方案 - 为基类提供显式构造函数 - 最好作为一般模式:

  • it avoids other classes inherited from Base forgetting to initialize m_a. 它避免了从Base继承的其他类忘记初始化m_a。 Instead, the signature of the class indicates initialization is required. 相反,类的签名表示需要初始化。

  • if multiple classes inherit from base, and initialization is more complex (eg a range check) , this code - and policy - is not distributed over multiple derived classes 如果多个类继承自base,并且初始化更复杂(例如范围检查),则此代码和策略不会分布在多个派生类上

  • if m_a is immutable, constructor initialization is required 如果m_a是不可变的,则需要构造函数初始化

  • derived classes might have more than one CTor, more places to forget 派生类可能有多个CTor,更多的地方要忘记

Only downside: a little more typing - as long as you don't count the additional "I'm a little lazy today so don't forget to init m_a in all derived classes constructors" 唯一的缺点:更多的打字 - 只要你不计算额外的“我今天有点懒,所以不要忘记在所有派生类构造函数中初始化m_a”

The "signature announces the requirements" is IMO sufficient to make this the default pattern, so is "the other way requires making m_a protected", as mentioned in the comments. “签名宣布要求”是IMO足以使其成为默认模式,因此“另一种方式需要使m_a受到保护”,如评论中所述。

I would prefer : 我会比较喜欢 :

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

By this way you make your code more encapsulated and Base members took care about its init list, there can be some more init logic in base class constructor depending on m_a instead of just initing m_a . 通过这种方式,您可以使代码更加封装, Base成员会关注其初始化列表,基类构造函数中可能会有更多的init逻辑,这取决于m_a,而不仅仅是初始化m_a In this case you pass initial value to your base constructor and then derived class in his constructor has initialized constructor of base class. 在这种情况下,您将初始值传递给基础构造函数,然后在其构造函数中派生类已初始化基类的构造函数。

You should try to pass init values to your Base class, imagine you have 5 Derived classes and you need to init base class at all of yours derived ctors. 您应该尝试将init值传递给Base类,假设您有5个Derived类,并且需要在所有派生的ctors中初始化基类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM