我有一个要求,我想在派生类中初始化一个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>任何建议???任何设计模式??
答案 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
的构造函数初始化之后),那么可以在Derived1
和Derived2
:
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
的构造函数。