在扩展模板的类中初始化static const

时间:2011-03-24 04:40:47

标签: c++ templates inheritance rtti

考虑这个伪代码:

class Foo {
public:
    virtual int getID() const = 0;
}

template<typename T>
class Blah : public Foo {
public:
    T data;
    static const int ID;  //static ID
    int getID() const { return Blah<T>::ID; }  //instance returns the ID
}

class Dude : public Blah<int> {
}
int Dude::ID = 10;  //I want to define Blah<int>::ID here, but how?

int receive(const Foo& foo) {
    if(foo.getID() == Dude::ID) {
        cout << "Received a Dude" << endl;
    }
}

这段代码无法编译,因为ISO C ++不允许将Blah模板中的ID定义为Dude类中的ID。我理解为什么,因为我可以有多个扩展Blah<int>的类。

我理解,如果我将template<typename T> int Blah<T>::ID = 10' in the Blah<T> impl表示它将起作用......但这不是我想要的......我希望派生类定义ID ......

我是否必须将ID和getID()推送到派生类中?我想最终我对一些RTTI感兴趣所以我可以适当地处理Foo。如果有人有更好的模式,我会全力以赴。

修改 回应一些评论......我想通过一些ID唯一地识别从Foo派生的类,这样我就可以将某些Foo对象的运行时ID与特定的类id进行比较。 / p>

谢谢!

3 个答案:

答案 0 :(得分:1)

制作静态int ID; private,并在公共接口中提供GetID,使SetID成为受保护的接口。但这不是一个好的解决方案,因为所有派生类都将共享相同的ID,这不是您想要的。

更好的方法是使用id作为基类的模板参数,然后类Derived:public Base&lt; 234&gt; {}将起作用。

或者将虚拟const int GetID()= 0添加到Base类中。

答案 1 :(得分:0)

我认为你可以这样做:

class Dude : public Blah<int> {
}
 static const int Dude_ID; //declaration!

int receive(const Foo& foo) {
    if(foo.getID() == Dude::Dude_ID) {
        cout << "Received a Dude" << endl;
    }
}
static const int Dude::Dude_ID = 10; // definition!

同样,为每个派生类定义一个ID。


为每个班级设置ID的另一种方法是:

template<typename T, int ID=1>
class Blah : public Foo {
public:
    int getID() const { return ID; }  
}

template<int ID=10>
class Dude : public Blah<int> {
public:
    int getID() const { return ID; }  
}

答案 2 :(得分:0)

我发现这个答案正是我所追求的......对不起,如果我的问题令人困惑。

in C++, how to use a singleton to ensure that each class has a unique integral ID?

相关问题