在运行时从指针到基类获取对象的类型
Get object's type from pointer to base class at runtime
我正在使用一个类库,其中所有类都直接或间接地从基类Base
派生并具有名称。库提供了通过名称搜索对象的功能,这将返回一个Base*
。
是否有任何方法可以找到返回对象的类型,而不像我在下面的例子中那样使用dynamic_cast
s检查所有可能性?如果可能的话,我希望避免这种情况,因为派生类有模板形参,这就产生了相当多的可能性。
如果我至少能够在不知道模板类型的情况下找到类类型(T1
或T2
,在下面的例子中),也会很好。像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
做一些有意义的事情。
我从一开始就意识到这是一个糟糕的设计,但是我被这个库困住了,我也没有办法改变它的实现。
有类似typeid
http://en.cppreference.com/w/cpp/language/typeid的东西,它应用于多态表达将在运行时评估其类型表示。
下面的wiki示例:https://en.wikipedia.org/wiki/Run-time_type_information#dynamic_cast
#include <iostream>
#include <typeinfo> // for 'typeid'
class Person {
public:
virtual ~Person() {}
};
class Employee : public Person {
};
int main()
{
Person person;
Employee employee;
Person* ptr = &employee;
Person& ref = employee;
// The string returned by typeid::name is implementation-defined
// Person (statically known at compile-time)
std::cout << typeid(person).name() << std::endl;
// Employee (statically known at compile-time)
std::cout << typeid(employee).name() << std::endl;
// Person* (statically known at compile-time)
std::cout << typeid(ptr).name() << std::endl;
/* Employee (looked up dynamically at run-time
* because it is the dereference of a
* pointer to a polymorphic class) */
std::cout << typeid(*ptr).name() << std::endl;
// Employee (references can also be polymorphic)
std::cout << typeid(ref).name() << std::endl;
}
有一个typeid
操作符,它返回一个std::type_info
的实例,您可以通过它获得类型的名称。
不确定这是否对你有帮助。首先,返回的名称不能保证在不同实现之间是相同的。第二,一旦你知道了名字,你会怎么做?您可能会将其与预定义的名称进行比较,但这可能比一堆dynamic_cast
慢。
Base
类中的类型支持或新的中间层次结构,dynamic_cast
是您的最佳选择。实际上它会非常快(通常只有一条比较指令)。
中间层的意思是:
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;
}
相关文章:
- 如何在C++中获取该对象的类声明中对象的地址?
- 如何在新的派生对象中获取基本对象的数据?
- 数组中不同类型的对象并获取每个对象的类型
- Visual Studio 2017 C++,不能使用 typeid() 获取信息对象,缺少指针?;
- 从两个 4x64 位整数数组中获取取模
- 如何从参数包获取指向对象的指针
- 在DelphiInterface上实现Dynamic_cast以获取基础对象类的任何方法
- 在<Object>基于范围的 for 循环中从 std::vector 获取指向对象的指针
- boost::可选 - 对对象使用 boost::in_place,构造器通过引用获取其他对象
- 如何使用 API 获取 QML 对象的 id 属性C++
- 如何从指针到方法获取类(对象类型)
- 在 C/C++ 中获取 Java 对象的内存地址
- 在ClrProfiler中,如何从ObjectID中获取托管对象
- 从操作员内部获取有关对象的RTTI信息
- 使用C 获取Java对象来调用Java方法
- 我们可以从设备句柄中获取设备对象详细信息 /名称吗?
- 从qgraphicsitem qt C 获取实际对象
- 如何获取成员对象以通知其容器对象
- 如何从静态对象中获取该对象的值
- 如何获取 COM 对象的成员函数的地址?