我有一个抽象基类,以及可能从其继承的多个对象。例如
class Mode {
public:
int n,l,m;
double omega;
virtual int doSomething() =0;
virtual ~Mode(){};
}
class ModeA : Mode {
ModeA(int N, int L, int M);
ModeA(double W, int L, int M);
virtual ~ModeA();
int doSomething();
}
class ModeB : Mode {
ModeB(int N, int L, int M);
ModeB(double W, int l, int M);
virtual ~ModeB();
int doSomething();
}
两个子类ModeA
和ModeB
的构造函数带有参数(int, int, int)
和(double, int, int)
。稍后,我有一段代码期望作为Mode
对象,看起来像
template <class MODE> int mode_finder(MODE** mode_list, int num_mode, int N, int L, int M){
assert((std::is_base_of<Mode,MODE>::value));
for(int i=0; i<num_mode; i++){
mode_list[i] = new MODE(N,L,M);
... some more code here ...
}
}
(这不仅仅是初始化模式列表的函数,...some more code here...
部分长约300行,包括检查列表中的值,如果不匹配则删除并重新创建-这个简单的工作示例中遗漏了很多东西)
如果我使用的是ModeA
和ModeB
,那很好,因为它们具有正确的构造函数。
我的问题是,我(或继承此代码的人)最终可能会创建一个新类型,而忘记放入这种形式的构造函数,例如
class ModeC : Mode {
ModeC(int X);
virtual ~modeC();
int doSomething();
}
在创建mode_maker
的功能模板时,如果我用ModeC
调用ModeC
,则会产生运行时错误。
我希望每个对象都从Mode
继承以实现具有两个签名的构造函数:(int, int, int)
和(double, int, int)
形式。如果没有,我想抛出一个编译时错误。
我认为纯虚拟构造函数可以解决问题,
virtual Mode(int, int, int) =0;
virtual Mode(double, int, int) =0;
,但显然由于vtable问题,这不是语言功能。我真的不需要vtable上的任何条目,我只需要强制子类构造这种类型的构造函数即可。
我该怎么做我想做的事情?
谢谢。
答案 0 :(得分:0)
在创建ModeC的功能模板时,如果我使用ModeC调用mode_maker,则会产生运行时错误。
不,不会。在编译时检查模板。
模板函数在编译时生成函数。模板类在编译时生成类。
您可能会对Java / C#中的泛型感到困惑,该泛型受模板的启发并满足模板的某些用途,并且更多地基于运行时。
C ++的泛型等效项是类型擦除类,例如std函数。当您与泛型进行交互时,它使用模板来创建Java / C#语言为您执行的粘合代码。我会考虑这样做(创建类型橡皮擦助手类型,而不是仅使用std函数)是C ++的高级用法。 Java / C#中有一些泛型用法,在C ++中需要这样做。不过,大多数用法都可以通过沼泽标准模板代码在C ++中进行仿真。