RTTI(Runtime Type Information)
RTTI代表运行时类型信息,它提供了运行时确定对象类型的方法。
typeid
-
头文件:
# include<typeinfo>
-
返回类型:
const type_info&
-
type_info
class type_info {
public:
virtual ~type_info();
size_t hash_code() const
_CRTIMP_PURE bool operator==(const type_info& rhs) const;
_CRTIMP_PURE bool operator!=(const type_info& rhs) const;
_CRTIMP_PURE int before(const type_info& rhs) const;
_CRTIMP_PURE const char* name() const;//返回类型对应的名字(具体所用的值,依赖于具体编译器
_CRTIMP_PURE const char* raw_name() const;
private:
type_info(const type_info& rhs);
type_info& operator=(const type_info& rhs);
};
注意:
- type_info类的默认构造函数和复制构造函数以及赋值操作符都定义为private,故不能定义或复制type_info类型的对象。
- 程序中创建type_info对象的唯一方法是使用typeid操作符。
举例
#include<iostream>
#include<typeinfo>
using namespace std;
class A
{
public:
void show() { cout << "A" << endl; }
};
class B :public A
{
public:
void show() { cout << "B" << endl; }
};
int main()
{
cout << typeid(int).name() << endl;
cout << typeid(char*).name() << endl;
cout << typeid(double).name() << endl;
cout << typeid(double *).name() << endl;
A* pa = new B();
cout << typeid(pa).name() << endl;
cout << typeid(*pa).name() << endl;
return 0;
}
虚函数
#include<iostream>
#include<typeinfo>
using namespace std;
class A
{
public:
virtual void show() { cout << "A" << endl; }
};
class B :public A
{
public:
void show() { cout << "B" << endl; }
};
int main()
{
cout << typeid(int).name() << endl;
cout << typeid(char*).name() << endl;
cout << typeid(double).name() << endl;
cout << typeid(double *).name() << endl;
A* pa = new B();
cout << typeid(pa).name() << endl;
cout << typeid(*pa).name() << endl;
return 0;
}
关于两次运行结果的不同,与静态关联和动态关联有关,可参考博客https://blog.csdn.net/qq_43313035/article/details/89421143
dynamic_cast
C++有四种强制类型转换符
dynamic_cast,const_cast,static_cast,reinterpret_cast。
其中dynamic_cast与运行时类型转换密切相关,在这里我们先介绍dynamic_cast,其他三种在后面介绍。
- 作用:将基类类型的指针或引用安全地转换为其派生类类型的指针或引用。
- dynamic_cast转换符只能用于含有虚函数的类
- 表达式形式:dynamic_cast<类型>(表达式)
举例:
p能成功转换为type*类型的情况:
1)p的类型是目标type的公有派生类:派生类向基类转换一定会成功。
2)p的类型是目标type的基类,当p是指向派生类对象的指针,或者引用派生类对象的基类引用时,类型转换才会成功
当p指向基类对象,试图转换为派生类对象时,转换失败
3)p的类型是type的类型时,一定会转换成功。
- 返回值
能成功转换则转换,返回正常cast后的对象指针.
转换失败,如果是指针则返回一个0值,如果转换的是引用,则抛出一个bad_cast异常
举例:
#include<iostream>
#include<typeinfo>
using namespace std;
class A
{
public:
virtual void show() { cout << "A" << endl; }
};
class B :public A
{
public:
void show() { cout << "B" << endl; }
};
class C :public A
{
public:
void show() { cout << "C" << endl; }
};
int main()
{
A ma;
B mb;
A* pa = new A;//A类型的而指针指向A类对象
A* pb = new B;//A 类型的指针指向派生类对象
B* pd = dynamic_cast<B*>(pa);//转换失败
cout << pd << endl;//0000000000000000
pd = dynamic_cast<B*>(pb);//转换成功
cout << pd << endl;
cout << typeid(pd).name() << endl;
//B& mb = dynamic_cast<B &> (*pa);//转换失败
B& md = dynamic_cast<B&>(*pb);//转换成功
cout << typeid(ma).name() << endl;
return 0;
}