【问题标题】:Initializing static const in a class that extends a template在扩展模板的类中初始化静态常量
【发布时间】:2011-03-24 04:40:46
【问题描述】:

考虑这个伪代码:

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&lt;int&gt; 的类。

我明白如果我输入template&lt;typename T&gt; int Blah&lt;T&gt;::ID = 10' in the Blah&lt;T&gt; impl 它将起作用...但这不是我想要的...我希望派生类定义 ID...

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

编辑 作为对某些 cmets 的回应...我想通过某个 ID 唯一标识派生自 Foo 的类,以便我可以将某些 Foo 对象的运行时 ID 与特定的类 ID 进行比较。

谢谢!

【问题讨论】:

标签: c++ templates inheritance rtti


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    我认为你可以简单地这样做:

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

    【讨论】:

    • 我在我的问题中提到了你的回答......我只是想知道我是否可以避免所有这些样板编码,因为我有几十个扩展 Blah 的类......
    • 我明白了...几个问题...你的意思是让 Dude 成为一个模板类...你不会只说 class Dude : public Blah
    • @T Reddy:是的,伙计,现在是一个类模板。由于 ID 具有默认值,这意味着您可以选择为其传递参数。 Blah&lt;int&gt;就够了!
    • @T Reddy:当然。但是您的语法略有不同,如果您不想传递参数(因为 Dude 的模板参数具有默认值),请执行以下操作:new Dude&lt;&gt;()。否则这样做:new Dude()`.
    • 我不认为这对我有用,因为 new Dude() 与 new Dude() 不同,例如......一个 Dude 只是一个 Dude恕我直言... ;)
    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-07-11
      • 2017-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-07
      • 2011-03-14
      相关资源
      最近更新 更多