我从库中获得了这些虚拟类,这些库以抽象类的形式实现了算法

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_castf()转换为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/

10-11 23:05
查看更多