RTTI运行时类型识别
创始人
2025-05-30 19:31:38
0

RTTI概念

RTTI是“运行时类型识别”的意思。

C++引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。它还能通过typeid操作符识别出所有的基本类型的变量对应的类型。

C++为了支持RTTI提供了两个操作符关键字:

typeid:类型获取

dynamic_cast:动态类型转化

typeid

在程序中用于获取一个表达式的类型。

typeid操作符实际的返回值是一个type_info类型的对象。

type_info类:

举例:

编译时获取类型信息

基本类型:

自定义类型:

注意:typeid在打印时会忽略变量的cv限定

没有产生多态的继承的关系中:

运行时获取类型信息

将上面的代码中,基类的析构函数设置为虚函数,产生多态

dynamic_cast中类型检测原理

我们对下面展示的类,在主函数中分别将

指向继承类Base的基类Object类指针 动态转化为 继承类Base指针

指向基类Object的基类Object类指针 动态转化为 继承类Base指针

  1. 指向继承类Base的基类Object类指针 动态转化为 继承类Base指针

我们运行后,打开监视器可以看到bp转化成功

  1. 指向基类Object的基类Object类指针 动态转化为 继承类Base指针

我们运行后,打开监视器可以看到bp转化失败为NULL

RTTI的实际用途

例如:模拟一个物品生成器。不懂种类的物品被放在同一个容器中,然后根据它们的动态类型分类。(货物:铜,纸张,玻璃)

#include
#include
using namespace std;
#include class Goods //货物
{
private:float weight; //重量
public:Goods(float w = 0.0f) :weight(w) {}float getweight()const { return weight; }virtual float getprice() = 0; //纯虚函数获取总价格virtual ~Goods() {}
};//铜
class Copper : public Goods
{
private:static float price;
public:Copper(float w = 0.0f) :Goods(w) {}float getprice() override{return getweight() * price;}~Copper() {}
};
float Copper::price = 2.80f;//纸
class Paper : public Goods
{
private:static float price;
public:Paper(float w = 0.0f) :Goods(w) {}float getprice() override{return getweight() * price;}
};
float Paper::price = 0.20f;//玻璃
class Glass : public Goods
{
private:static float price;
public:Glass(float w = 0.0f) :Goods(w) {}float getprice() override{return getweight() * price;}
};
float Glass::price = 0.32f;vector putinto_vactor()
{srand(time(nullptr));int n = rand() % 10;vector bin;for (int i = 0; i < n; i++){switch (rand() % 3){case 0:bin.push_back(new Copper(rand() % 1000 / 10.0));break;case 1:bin.push_back(new Paper(rand() % 1000 / 10.0));break;case 2:bin.push_back(new Glass(rand() % 1000 / 10.0));break;}}return bin;
}int main()
{//将所有货物添加到货物容器中vector bin = putinto_vactor();//对不同的货物分类vector copbin;vector papbin;vector glabin;for (auto x : bin){Copper* cp = dynamic_cast(x); //动态转化失败就会返回nullptrPaper* pp = dynamic_cast(x);  //动态转化失败就会返回nullptrGlass* gp = dynamic_cast(x);  //动态转化失败就会返回nullptrif (cp != nullptr){copbin.push_back(cp);}else if (pp != nullptr){papbin.push_back(pp);}else if (gp != nullptr){glabin.push_back(gp);}}//计算总价格float total = 0.0f;for (auto x : copbin){cout << "Copper weight =" << x->getweight() << endl;total += x->getprice();}cout << "Copper total price =" << total << endl << endl;total = 0.0f;for (auto x : papbin){cout << "Paper weight =" << x->getweight() << endl;total += x->getprice();}cout << "Paper total price =" << total << endl << endl;total = 0.0f;for (auto x : glabin){cout << "Glass weight =" << x->getweight() << endl;total += x->getprice();}cout << "Glass total price =" << total << endl << endl;return 0;
}

运行结果:

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...