在运行时确定对象类型的最佳方法

时间:2015-11-08 07:29:08

标签: c++ c++11 design-patterns rtti

所以我要做的是实现消息模式。据我所知,用户将根据我输入的消息类型,而不是执行操作的消息类型。因此,我就这样做了:

我想获取对象的数据类型,以便我可以执行switch语句,但我不确定从哪里开始。

我已经浏览了谷歌并做了一些研究,但没有一个成功。这就是我的尝试:

  • Decltype:甚至不接近我想要的
  • typeof:我不太清楚如何使用
  • 动态演员:不接近我想要的

基本上,我最终想要的是这样的:

switch (typeof(a)) {
    class_a : //do something
    class_b : //do something
}

if语句对我来说也是一样的。谁能帮我吗?我更喜欢使用标准库。

2 个答案:

答案 0 :(得分:2)

标准C ++中没有typeof(尽管该名称有一个GCC扩展名)。您正在寻找typeid运营商。这将返回对static const std::type_info实例的引用,该实例包含对象的运行时类型信息(RTTI)。您可以将结果与您感兴趣的各个类的typeid进行比较。

作为一个简单的例子(see it run at ideone):

#include <iostream>
#include <typeinfo>

class A {
public:
    virtual ~A() {}
};

class B: public A {};
class C: public A {};


int main() {
    const A& a = C{};

    const auto& id = typeid(a);

    if(id == typeid(B)) {
        std::cout << "Got a B." << std::endl;
    }
    else if(id == typeid(C)) {
        std::cout << "It's a C!" << std::endl;
    }

    return 0;
}

(请注意,您无法使用switch,因为这些对象不是整数。)此示例将打印It's a C!

请注意,一般情况下,使用RTTI不应该是您的第一反应(尤其是如果您来自Java等语言,其中动态类型及其相关的速度命中率)理所当然。)

与其他面向对象的范例相比,RTTI相对较慢,甚至是动态调度(virtual函数)。如果您正在尝试实现消息模式,请考虑将显式值作为消息传递,而不是将其他对象强行插入到模式中并导致RTTI的昂贵开销。

答案 1 :(得分:0)

  

动态演员:不接近我想要的

你错了。动态演员当然可以做你想要的。

if (dynamic_cast<c1*>(a)) { ... }
else if (dynamic_cast<c2*>(a)) { ... }

*a的静态类型必须是多态的。同样适用于参考。如果按值传递它,它不会也不能工作。

然而,这是一种危险且容易出错的方式。如果要为M个收件人类型实现N个消息类型,并且所有M×N操作可能不同,请考虑使用访问者模式,尤其是非循环实现。