C++ RTTI 和派生类

Posted

技术标签:

【中文标题】C++ RTTI 和派生类【英文标题】:C++ RTTI and Derived Classes 【发布时间】:2009-12-15 00:59:04 【问题描述】:

我的 C++ 有点生疏了。这是我正在尝试做的事情:

class Cmd  ;
class CmdA : public Cmd  ;
class CmdB : public Cmd  ;
...
Cmd *a = new CmdA ();
Cmd *b = new CmdB ();

第一个问题:

cout << typeid (a).name ()
cout << typeid (b).name ()

两者都返回 Cmd * 类型。我想要的结果是 CmdA* 和 CmdB*。任何 除了:

if (dynamic_cast <CmdA *> (a)) ...

其次,我想做这样的事情:

class Target 
    public:
        void handleCommand (Cmd *c)  cout << "generic command..." 
        void handleCommand (CmdA *a)  cout << "Cmd A"; 
        void handleCommand (CmdB *b)  cout << "Cmd B"; 
;

Target t;
t.handleCommand (a);
t.handleCommand (b);

并获得输出“Cmd A”和“Cmd B”。现在它打印出来 “通用命令...”两次。

谢谢

【问题讨论】:

【参考方案1】:

啊,但是typeid(a).name() 将是Cmd*,因为它定义为Cmd*typeid(*a).name() 应该返回 CmdA

http://en.wikipedia.org/wiki/Typeid

此外,你传递给 typeid 的任何东西的基类都必须有虚函数,否则你会得到基类。

MSDN 对此有更雄辩的解释:

如果表达式指向一个基 类类型,但对象实际上是 从该基派生的类型 类,一个 type_info 参考 派生类是结果。这 表达式必须指向多态 类型(具有虚函数的类)。 否则,结果为 type_info 对于中提到的静态类 表达方式。此外,指针 必须取消引用,以便 它指向的对象被使用。没有 取消引用指针,结果 将是指针的 type_info, 不是它所指向的。

【讨论】:

啊,是的。我缺少的另一件事是在 Cmd 中至少有一个虚拟功能。虚拟 ~Cmd () 【参考方案2】:

看起来您正在执行双重/多重调度...看看here for some info for hacking it into C++。还请查看访问者模式。

我认为您本质上想要做的是动态转换来确定类型,然后是静态转换来调用适当的句柄命令。话虽如此,我的 C++ 也生锈了 :-)

【讨论】:

以上是关于C++ RTTI 和派生类的主要内容,如果未能解决你的问题,请参考以下文章

java的RTTI和反射机制

运行时类型识别RTTI

关于C++基类与派生类

关于C++基类、派生类的引用和指针

C++中的基类和派生类

运行时类型识别