RTTI是“运行时类型识别”的意思。
C++引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。它还能通过typeid操作符识别出所有的基本类型的变量对应的类型。
C++为了支持RTTI提供了两个操作符关键字:
typeid:类型获取
dynamic_cast:动态类型转化
在程序中用于获取一个表达式的类型。
typeid操作符实际的返回值是一个type_info类型的对象。
举例:
基本类型:
自定义类型:
注意:typeid在打印时会忽略变量的cv限定
没有产生多态的继承的关系中:
将上面的代码中,基类的析构函数设置为虚函数,产生多态
我们对下面展示的类,在主函数中分别将
指向继承类Base的基类Object类指针 动态转化为 继承类Base指针
指向基类Object的基类Object类指针 动态转化为 继承类Base指针
指向继承类Base的基类Object类指针 动态转化为 继承类Base指针
我们运行后,打开监视器可以看到bp转化成功
指向基类Object的基类Object类指针 动态转化为 继承类Base指针
我们运行后,打开监视器可以看到bp转化失败为NULL
例如:模拟一个物品生成器。不懂种类的物品被放在同一个容器中,然后根据它们的动态类型分类。(货物:铜,纸张,玻璃)
#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;
}
运行结果: