我有两个抽象类,fooBase和barBase。它们都有两个(或更多)具体的子类(foo1foo2bar1bar2)。我希望barBase的每个子类的方法都调用与fooBase中的一个具体类相对应的方法。例如,

class fooBase{
    virtual int method()=0;
};

class foo1 : public fooBase {
    public :
    foo1(){}
    int method(){return 1;}
};

class foo2 : public fooBase {
    public :
    foo2(){}
    int method(){return 2;}
};

class barBase {
    virtual int drilldown(fooBase &)=0;
};

class bar1 : public barBase {
    public :
    bar1(){}
    int drilldown(foo1 & f){return f.method();}
};

class bar2 : public barBase {
    public :
    bar2(){}
    int drilldown(foo2 & f){return f.method();}
};


然后在main()中执行:

    foo1 f1;
    foo2 f2;
    bar1 b1;
    bar2 b2;


但是我得到了错误:Variable type 'b1' is an abstract class(对于b2同样如此)。我知道这种情况的发生是因为drilldown中的barBase方法是使用对fooBase抽象类的引用的参数定义的,但是bar1和bar2试图深入研究具体的子类,因此编译器不会这样做。 t认识到drilldown(fooBase &)的方法是在子类中定义的。如何解决此问题,以便获得所需的行为?在这种情况下正确的设计模式是什么?



我最终使用了Joachim Pileborg的解决方案(请参见下文)。我还必须将带有barBase&参数的任何函数更改为模板函数,即

 template<class T>
 int fn(barBase<T> & b, T & f){
    return b.drilldown(f);
 }


int main(int argc, const char * argv[])
{
    foo1 f1;
    foo2 f2;
    bar1 b1;
    bar2 b2;
    std::cout<<b1.drilldown(f1);
    fn(b1,f1);
return 0;
}

最佳答案

您可以将barBase定义为模板,例如

template<typename T>
struct barBase {
    virtual int drilldown(T &)=0;
};

class bar1 : public barBase<foo1> {
    public :
    bar1(){}
    int drilldown(foo1 & f){return f.method();}
};

class bar2 : public barBase<foo2> {
    public :
    bar2(){}
    int drilldown(foo2 & f){return f.method();}
};


当然,它的缺点是您不能使用指针或对barBase的引用来引用其子类之一。

09-26 15:12