在C++中查找对象的类型

lem*_*sca 135 c++ types

我有一个A类和另一个继承它的类,B.我重写了一个接受A类对象作为参数的函数,所以我必须接受一个A.但是,我后来调用只有B的函数,所以我想返回false,如果传递的对象不是B类,则不继续.

找出传递给我的函数的对象的最佳方法是什么?

yes*_*aaj 151

dynamic_cast应该可以解决问题

TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
Run Code Online (Sandbox Code Playgroud)

dynamic_cast关键字从一个指针或引用类型转换基准到另一个,执行运行时检查以确保铸造的有效性.

如果您尝试转换为指向不是实际对象类型的类型的指针,则转换的结果将为NULL.如果您尝试强制转换为引用不是实际对象类型的类型,则强制类型转换将抛出bad_cast异常.

确保Base类中至少有一个虚函数可以使dynamic_cast工作.

  • OK 找到了:运行时类型信息 (RTTI) 仅适用于多态的类,这意味着它们至少有一个虚拟方法。dynamic_cast 和 typeid 需要 RTTI。 (3认同)

Rob*_*ide 142

动态强制转换最适合您对问题的描述,但我只想补充一点,您可以找到类类型:

#include <typeinfo>

...
string s = typeid(YourClass).name()
Run Code Online (Sandbox Code Playgroud)

  • 我[看不到](http://coliru.stacked-crooked.com/a/389a90a2e3e0713e)如何.类型ID名称不需要有用,并且是实现定义的. (7认同)
  • @xus是的.它是标准头文件的一部分 (4认同)
  • 如果你真的不知道你的对象是什么,那就太好了.接受的答案假定你这样做. (3认同)
  • 最有趣的是:同一个类的实例名称不必相等.但是,typeid本身必须比较相同类的实例,请参阅/sf/ask/139049291/ (3认同)
  • 注意 gcc 返回 magled 名称,例如 `11MyClass`。要取消损坏,您可以使用“cxxabi.h”中的 ABI 扩展库。这将为您提供“abi::__cxa_demangle”,它将为您提供真实姓名 (2认同)

Ana*_*tts 24

这被称为RTTI,但你几乎肯定想在这里重新考虑你的设计,因为找到类型并根据它做特殊的事情会使你的代码变得更脆弱.

  • 真正.不幸的是,我正在研究一个现有的项目,所以我不能真正改变设计,或A类中的任何东西. (3认同)

fre*_*ace 9

可能会在您的对象中嵌入一个ID"标记",并用它来区分A类对象和B类对象.

然而,这显示了设计中的缺陷.理想情况下,A中没有的那些方法应该是A的一部分而是留空,而B则覆盖它们.这取消了特定于类的代码,更符合OOP的精神.


fir*_*ush 8

为了完成,我将构建Robocide构建并指出typeid可以单独使用而不使用name():

#include <typeinfo>
#include <iostream>

using namespace std;

class A {
public:
    virtual ~A() = default; // We're not polymorphic unless we
                            // have a virtual function.
};
class B : public A { } ;
class C : public A { } ;

int
main(int argc, char* argv[])
{
    B b;
    A& a = b;

    cout << "a is B: " << boolalpha << (typeid(a) == typeid(B)) << endl;
    cout << "a is C: " << boolalpha << (typeid(a) == typeid(C)) << endl;
    cout << "b is B: " << boolalpha << (typeid(b) == typeid(B)) << endl;
    cout << "b is A: " << boolalpha << (typeid(b) == typeid(A)) << endl;
    cout << "b is C: " << boolalpha << (typeid(b) == typeid(C)) << endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

a is B: true
a is C: false
b is B: true
b is A: false
b is C: false
Run Code Online (Sandbox Code Playgroud)


Jos*_*hua 7

你在找dynamic_cast<B*>(pointer)