我从库中获得了这些虚拟类,这些库以抽象类的形式实现了算法
class A{
public :
virtual void foo() = 0 ;
};
class B{
public:
void setA(A * a) { m_a = a ;}
virtual void f() = 0;
void g() {m_a->foo();}
protected:
A * m_a ;
};
要使用该库,您只需要派生类并实现纯虚函数(如
foo()
),并提供特定于实现的其他方法(bar()
)。class dA : public A {
public :
void foo() {/* ... */}
void bar() {/* ... */}
};
class dB : public B {
public :
void f() ;
};
我通常会通过调用这些类来使用
dB * mydB = new dB() ;
mydB->setA(new dA() );
mydB->f() ;
mydB->g() ;
但是实现
dB::f()
时遇到设计问题,因为我需要调用特定于dA::bar()
的dB
。但是在课堂上,我仅参考B *的dB。然后我想到了两个选择:每次调用
dynamic_cast
将f()
转换为B::m_a
时都使用dB*
向dB添加一个m_dA成员,该成员存储与m_a相同的指针,但可用于访问特定于dB的功能。
当然,我不能更改基类。
我想知道是否有一个更优雅的解决方案(例如我没有想到的设计模式)。如果没有,我应该选择哪一个?
最佳答案
您有第三个解决方案。在setA()
中添加功能dB
。当然,如果将B::setA()
实现为以下功能,该函数将隐藏dB::setA()
,这对您有好处:
class dB : public B
{
dA *m_dA ; //add this member also!
public :
void f()
{
m_dA->bar(); //fast forward : no cast here!
}
void setA(A *a) //this hides B::setA()
{
m_dA= dynamic_cast<dA*>(a); //just one time dynamic cast!
if ( m_dA == 0 )
{
throw std::runtime_error("invalid argument");
}
B::setA(a); //now call the hidden function in the base!
}
};
这样,您不必每次调用
dB::f()
时都进行dynamic_cast,这使调用速度更快!关于c++ - 组成与继承设计问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6833184/