在运行时从指向基类的指针获取对象的类型 [英] Get object's type from pointer to base class at runtime

查看:94
本文介绍了在运行时从指向基类的指针获取对象的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个类库,其中所有类都直接或间接地从基类 Base 派生并具有名称。该库提供了一种通过名称搜索对象的功能,该名称将返回 Base *

I'm working with a class library where all classes are, directly or indirectly, derived from a base class Base and have a name. The library provides a facility to search for objects by a name, which will return a Base*.

是否存在像下面的示例一样,有什么方法可以找到返回对象的类型,而无需使用 dynamic_cast s检查所有可能性?如果可能的话,我想避免这种情况,因为派生类具有模板参数,因此有很多可能性。

Is there any way to find the type of the returned object without checking all possibilities using dynamic_casts as I did in the following example? I'd like to avoid that, if at all possible, since the derived classes have template parameters, which makes for quite a few possibilities.

如果我至少能够找出类类型(在下面的示例中为 T1 T2 ),而无需知道模板类型,即做类似 dynamic_cast< T1< i_dont_care> *> 的事情。

It would also be fine if I were at least able to find out the class type (T1 or T2, in the example below) without knowing the template type, ie. do something like a dynamic_cast<T1<i_dont_care>*>.

#include <iostream>

using namespace std;

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

template <typename T> class T1 : public Base {};
template <typename T> class T2 : public Base {};

Base *find_by_name() {
    return new T2<int>();
}

int main() {
    Base *b = find_by_name();

    if (T1<int> *p = dynamic_cast<T1<int>*>(b)) {
        cout << "T1<int>" << endl;
        // do something meaningful with p
    } else if (T1<double> *p = dynamic_cast<T1<double>*>(b))
        cout << "T1<double>" << endl;
    else if (T2<int> *p = dynamic_cast<T2<int>*>(b))
        cout << "T2<int>" << endl;
    else if (T2<double> *p = dynamic_cast<T2<double>*>(b))
        cout << "T2<double>" << endl;
    else
        cout << "unknown" << endl;

    delete b;

    return 0;
}

请注意,以上示例已简化。在每个 if 中,我都会对 p 做一些有意义的事情。

Note that the above example is simplified, ie. in each if I'd do something meaningful with p.

我确实从一开始就意识到这是一个不好的设计,但是我仍然坚持使用这个库,也没有办法改变它的实现。

I do realize that this is bad design from the very start, however I'm stuck with this library and there's also no way for me to change its implementation.

推荐答案

有一个 typeid 运算符,它返回 std :: type_info ,通过它可以获取类型的名称。

There is a typeid operator, which returns an instance of std::type_info, with which you can get the name of the type.

不确定是否有帮助虽然你。首先,不能保证返回的名称在各个实现中都相同。第二-取名后该怎么办?您可以将其与您的预定义名称进行比较,但这可能比一堆 dynamic_cast 的速度慢。

Not sure if that will help you though. First, the returned name is not guaranteed to be the same across implementations. Second - what would you do once you have the name? You'd compare it with your pre-defined names probably, but that is probably slower than a bunch of dynamic_cast's.

在您的 Base 类中没有内置类型支持,或者没有新的中间层次结构, dynamic_cast 是您的最佳选择选择。实际上,它会非常快(通常只有一条比较指令)。

Without type support built into your Base class or a new intermediate layer of hierarchy, dynamic_cast is your best choice. In reality it will be very fast (usually just a single compare instruction).

通过中间层,我的意思是:

By intermediate layer I mean:

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

class T1Base : public Base {};
class T2Base : public Base {};

template <typename T> class T1 : public T1Base {};
template <typename T> class T2 : public T2Base {};

int main() {
    Base *b = find_by_name();

    if (dynamic_cast<T1Base*>(b))
        cout << "T1" << endl;
    else if (dynamic_cast<T2Base*>(b))
        cout << "T2" << endl;
    else
        cout << "unknown" << endl;

    delete b;

    return 0;
}

这篇关于在运行时从指向基类的指针获取对象的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆