2011-03-24 48 views
2

考虑这个伪代码的类:初始化静态常量在于延伸的模板

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被定义为ID在类Dude。我明白为什么,因为我可以有多个类别延伸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类。

谢谢!

+0

我不知道我是否正确理解问题。你检查过CRTP吗?这可能有用。 http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern – Asha 2011-03-24 04:44:43

+0

@Asha:我不熟悉CRTP ......但我不相信我想用Dude作为模板参数。 – 2011-03-24 04:49:50

+1

你在问[关于一个步骤而不是一个目标](http://www.catb.org/~esr/faqs/smart-questions.html),这使[它不可能回答](http:// jalf.dk/blog/2010/09/yes-youre-going-to-have-to-tell-me-what-your-question-is-before-i-can-answer-it/)。你想达到什么目的? – GManNickG 2011-03-24 04:56:46

回答

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; } 
} 
+0

我在我的问题中提到你的答案......我只是想知道如果我能避免所有的样板编码,因为我有几十个类扩展Blah ... – 2011-03-24 05:10:48

+0

@T Reddy:请参阅我的编辑。 – Nawaz 2011-03-24 05:16:34

+0

我看到......有几个问题......你的意思是让Dude成为一个模板班......你不只是说Dude类:public Blah ? – 2011-03-24 05:25:26

1

使静态INT ID;私人,并提供公共接口的GetID,使SetID成为一个受保护的接口。但这不是一个好的解决方案,因为所有的派生类将共享相同的ID,这不是你想要的。

更好的方法应该是使用id作为基类的模板参数,然后使用Derived类:public Base < 234> {}将会工作。

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