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

Best way to determine the type of an object at runtime

本文关键字:最佳 方式 类型 对象 运行时      更新时间:2023-10-16

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

我想得到对象的数据类型,这样我就可以执行switch语句,但我不太确定从哪里开始。

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

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

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

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

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

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

作为一个微不足道的例子(请参阅它在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等语言,在这些语言中,动态键入及其相关的速度打击被视为理所当然)。

与其他面向对象的范例,甚至动态调度(virtual函数)相比,RTTI相对较慢。如果您试图实现Message模式,请考虑将显式值作为消息传递,而不是将其他对象硬塞进模式中,从而导致RTTI的昂贵开销。

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

你拿错了。动态演员阵容当然可以随心所欲。

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

*a的静态类型必须是多态的。参考资料也是如此。如果您按值传递它,它不会也不可能工作。

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