使用某些条件初始化派生类中的基类成员变量

Initialize a base class member variable in derived class with some conditions

本文关键字:基类 成员 变量 派生 条件 初始化      更新时间:2023-10-16

我有一个要求,我想在派生类中初始化基类成员。

class SuperBase
{
public:
    virtual void Set();
};
class Base:public SuperBase
{
protected:
    int *pVal;
public:
    void Set()
    {
       //Some Logic
    }
};
class Derived1: public Base
{
public:
   // I want to Initialize Base::pVal here and after 
   // that I want to have this value in Set() of Base.
};
class Derived2: public Base
{
  //...Same functionality as Derived1; 
  //...
};
int main()
{
  SuperBase *s = new Derived1; 
  // Here when I create a Derived1 object automatically, 
  // the value for pVal will be initialized 
  s->Set();
 //After calling this Set, I want to get the pVal value access in Set.
}

我知道这是一件容易的事情。但这些是我不能用于这个问题的东西:

  • 我不能使用构造函数初始值设定项列表将值从派生类传递到 Base [我知道我可以通过构造函数初始化器列表轻松做到这一点,但有一个要求,我不想要现有的类构造函数]

  • 我尝试过使用 CRTP[奇怪的重复模板模式],但这也不合适,因为它使用一种静态绑定,并且在更高的视图中,我必须在运行时决定调用哪个类对象 Derived1,Derived2。

  • 我也不想在 Derived1,Derived2 中编写任何 get(),因为我只想在那里分配值。这也是我要求的一部分。

  • 我希望 Set 逻辑仅存在于 Base 类中,如果 Set 有任何特殊情况,那么我将覆盖派生类中的 Set,否则我将从 Base 访问它。

有什么建议吗???任何设计模式??

我直言,你可以这样做:

选项 1 :a) 覆盖 derived1 中的 set();

b) 在派生1::设置中,
-- 分配 pVal 所需值。

-- 呼叫库::设置

示例代码:

void Derived::Set(){
    pVal = /*some value*/;
    Base::Set(); 
}

选项2:正如Angew所指出

class Derived1: public Base
{
 public:
  Derived()
  {
    pVal = /*some value*/;
  }
};

SuperBase *s = new Derived1;将调用上述构造函数并设置pVal

只能在类构造函数的成员初始化器列表中初始化类的数据成员。别无他法。因此,如果您需要初始化,则必须添加一个适当的构造函数来Base并使用它(当然,它可以protected)。

另一方面,如果将一个值分配给pVal就足够了(在它被Base的构造函数初始化之后),你可以简单地在 Derived1Derived2 的构造函数的主体中执行此操作:

class Derived1: public Base
{
public:
  Derived()
  {
    pVal = whatever;
  }
};

为此创建构造函数。

class Base: public SuperBase {
public:
    Base() : pVal(0) {} // Default constructor
protected:
    int *pVal;
    Base(int* Val = 0 /* default value */) : pVal(Val) {} // special constructor
    ...
};
class Derived1: public Base {
public:
   Derived1() : Base(p1 /* Set whatever you want here */) {
   }
};
class Derived2: public Base {
public:
   Derived2() : Base(p2 /* Set other value here */) {
   }
};

您可以在Derived1/Derived2类和具有初始化pVal的构造函数的Base类之间添加另一个继承级别。