在C++ 11中检查对象类型

pro*_*eek 5 c++ rtti typeid c++11

我有继承自A的B类.

class A
{
};

class B : public A
{
};
Run Code Online (Sandbox Code Playgroud)

我有三个对象.

A* a = new A();
A* a2 = new B();
B* b = new B();
Run Code Online (Sandbox Code Playgroud)

我想如果检查a是A类型的对象,a2是B类型的对象(不是A),b是B类型的对象.

我试过打字比较,但它没有给我正确的答案.

cout << (typeid(*a) == typeid(A)) << endl; // -> 1
cout << (typeid(*a2) == typeid(A)) << endl; // -> 1
cout << (typeid(*b) == typeid(A)) << endl; // -> 0

cout << (typeid(*a) == typeid(B)) << endl; // -> 0
cout << (typeid(*a2) == typeid(B)) << endl; // -> 0
cout << (typeid(*b) == typeid(B)) << endl; // -> 1
Run Code Online (Sandbox Code Playgroud)

我尝试了动态转换,但是我遇到了编译错误.

B* derived = dynamic_cast<B*>(a);
if (derived) {
    cout << "a is B";
}
derived = dynamic_cast<B*>(a2);
if (derived) {
    cout << "a2 is B";
}
derived = dynamic_cast<B*>(b);
if (derived) {
    cout << "b is B";
}

typename.cpp: In function 'int main(int, char**)':
typename.cpp:27:36: error: cannot dynamic_cast 'a' (of type 'class A*') to type 'class B*' (source type is not polymorphic)
     B* derived = dynamic_cast<B*>(a);
                                    ^
typename.cpp:31:34: error: cannot dynamic_cast 'a2' (of type 'class A*') to type 'class B*' (source type is not polymorphic)
     derived = dynamic_cast<B*>(a2);
Run Code Online (Sandbox Code Playgroud)

我使用静态铸造,但我的答案错了.

B* derived = static_cast<B*>(a);
if (derived) {
    cout << "a is B"; // -> YES
}
derived = static_cast<B*>(a2);
if (derived) {
    cout << "a2 is B"; // -> YES
}
derived = dynamic_cast<B*>(b);
if (derived) {
    cout << "b is B"; // -> YES
}
Run Code Online (Sandbox Code Playgroud)

如何在C++ 11中正确识别对象类型?

And*_*zos 10

有些类是多态的,有些是非多态的.

多态类具有一个或多个虚函数(可能是继承的),非多态类具有零虚函数.

你的A和B是非多态的.

A和B的多态版本将展示您想要的行为:

#include <iostream>
#include <typeinfo>

using namespace std;

struct A
{
    virtual ~A() {}; // add virtual function
};

class B : public A
{
};

A* a = new A();
A* a2 = new B();
B* b = new B();

int main()
{
    cout << (typeid(*a) == typeid(A)) << endl; // -> 1
    cout << (typeid(*a2) == typeid(A)) << endl; // -> 0 <-- CHANGED
    cout << (typeid(*b) == typeid(A)) << endl; // -> 0

    cout << (typeid(*a) == typeid(B)) << endl; // -> 0
    cout << (typeid(*a2) == typeid(B)) << endl; // -> 1 <-- CHANGED
    cout << (typeid(*b) == typeid(B)) << endl; // -> 1
}
Run Code Online (Sandbox Code Playgroud)

多态类的实例在运行时存储其最派生对象的动态类型.

(在你的榜样a2是类型指针到-A,并且在A型的目标指向,然而这对象只是一个基类子对象的的最dervived对象类型B的你想获得什么类型查询时这个派生对象B最多a2.为此你需要一个多态类.)

这就是多态类支持dynamic_casttypeid派生的对象(以及虚函数调度)的方式.

非多态类没有此信息,因此它们只能报告编译时已知的静态类型.非多态类比多态类更紧凑和有效.这就是为什么不是所有的C++类都是多态的.语言让程序员选择在性能和功能之间进行权衡.例如:

struct X { int x; };
struct Y : X {};
struct Z : Y {};
Run Code Online (Sandbox Code Playgroud)

在我的系统非多态性Zsizeof(Z) == 4 bytes,同一个int.

struct X { int x; virtual ~X() {}; };
struct Y : X {};
struct Z : Y {};
Run Code Online (Sandbox Code Playgroud)

现在制作Z多态后,sizeof(Z) == 16 bytes.因此,Z的数组现在大300%,因为每个Z实例都必须在运行时存储其类型信息.

  • @Sharth:不,[那不是真的](http://stackoverflow.com/a/17222286/560648); 你没有在_either_ case中得到它. (2认同)