RTT机制

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;
}

猜你喜欢

转载自blog.csdn.net/qq_43313035/article/details/89508123
RTT