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

Best way to determine the type of an object at runtime

所以我想做的是实现消息模式。据我了解,用户将根据我输入的消息类型采取行动,而不是执行操作的消息类型。因此,这就是我的处理方式:

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

我查看了 google 并做了一些研究,但 none 是成功的。这是我试过的:

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

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

if 语句对我来说同样有效。谁能帮我吗?我更喜欢使用标准库。

标准 C++ 中没有 typeof(尽管有一个 GCC 扩展名)。您正在寻找包含对象的 运行 时间类型信息 (RTTI) 的 typeid operator. This returns a reference to a static const std::type_info 实例。您可以将结果与您感兴趣的各种 类 的 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 开销。

dynamic-cast : not close to what I want

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

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

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

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