我有两个抽象类,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正试图深入到具体子类,因此编译器无法识别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;
}
答案 0 :(得分:1)
似乎你只需要:
class barBase {
int drilldown(fooBase &f){ return f.method(); }
};
和你假设的功能:
int f(barBase & b, fooBase & f){return b.drilldown(f);}
工作得很好。
答案 1 :(得分: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
的引用来引用它的任何一个子类。