我之前(Here)发布了这个问题,这是解决方案的另一种方法。这个解决方案似乎可以更好地封装那些实现类的人的行为,因为它可以防止他们需要显式地强制转换。
问题在于:
我有一个项目,我希望在大多数对象中隔离核心行为,同时通过派生对象提供额外的行为。很简单:
class BaseA
{
virtual void something() {}
}
class DerivedA : public BaseA
{
void something() {}
void somethingElse() {}
}
现在让我说我还有第二组类,相同的继承方案,除了它们聚合上面的类。但是,我希望基本版本使用基类,并在派生类中使用派生版本。我的解决方案是考虑使用相同的名称“隐藏”基类变量;
class BaseB
{
BaseA *var;
BaseB()
{
var = new BaseA();
}
virtual void anotherThing1();
virtual void anotherThing2();
virtual void anotherThing3();
}
class DerivedB : public BaseB
{
DerivedA *var;
DerivedB()
{
var = new DerivedA();
}
void anotherThing1();
void anotherThing2();
void anotherThing3();
void andAnother1();
void andAnother2();
}
这种方法的目标是使依赖派生聚合类的函数不再需要显式转换以实现获得的功能。
void func1( BaseB &b )
{
b.anotherThing1();
b.var->something();
}
void func2( DerivedB &b )
{
b.anotherThing1();
b.andAnother1();
b.var->something();
b.var->somethingElse();
}
void main( int argc, char **argv )
{
BaseB baseB;
DerivedB derivedB;
func1( baseB );
func1( derivedB );
func2( derivedB );
}
这会被视为不良做法吗?
答案 0 :(得分:1)
这会被视为不良做法吗?
是的,这是不好的做法,因为var
中的Base
将不被使用。看起来DerivedB
不应该来自BaseB
:相反,它们应该来自同一个抽象基类,如下所示:
class AbstractB {
public:
virtual void anotherThing1() = 0;
virtual void anotherThing2() = 0;
virtual void anotherThing3() = 0;
};
class DerivedB1 : public AbstractB { // Former BaseB
BaseA *var;
public:
DerivedB1() {
var = new BaseA();
}
virtual void anotherThing1();
virtual void anotherThing2();
virtual void anotherThing3();
};
class DerivedB2 : public AbstractB { // Former DerivedB
DerivedA *var;
public:
DerivedB2() {
var = new DerivedA();
}
void anotherThing1();
void anotherThing2();
void anotherThing3();
void andAnother1();
void andAnother2();
};
这里使用的一般原则是你应该尝试在继承层次结构中抽象所有非叶类。