在某些条件下,在派生类中初始化基类成员变量

时间:2013-09-11 06:08:42

标签: c++ oop design-patterns

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

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 [我知道我可以通过构造函数初始化列表轻松地执行此操作,但有一个要求我不希望现有的类构造函数] < / p>

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

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

  • 我希望Set逻辑只出现在Base类中,如果有任何Set的特殊情况,那么我将覆盖Derived类中的Set,否则我将从Base访问它。

    < / LI>

任何建议???任何设计模式??

4 个答案:

答案 0 :(得分:3)

恕我直言,你可以这样做:

选项1: a)覆盖Derived1中的Set();

b)在Derived1 :: Set中,
    - 分配pVal期望值。

- Call Base :: Set

示例代码:

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

    Base::Set(); 

}

选项2:正如Angew指出的那样

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

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

答案 1 :(得分:1)

您只能在该类的构造函数的member-initialiser-list中初始化类的数据成员。别无他法。因此,如果您需要初始化,则必须向Base添加适当的构造函数并使用它(当然,它可以是protected。)

另一方面,如果你的目的足以值分配到pVal(在Base的构造函数初始化之后),那么可以在Derived1Derived2

的构造函数的主体中执行此操作
class Derived1: public Base
{
public:
  Derived()
  {
    pVal = whatever;
  }
};

答案 2 :(得分:1)

为此目的创建构造函数。

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 */) {
   }
};

答案 3 :(得分:0)

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