我有两个抽象类,fooBase和barBase。它们都有两个(或更多)具体的子类(foo1
,foo2
和bar1
,bar2
)。我希望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
的引用来引用其子类之一。