C++基础#21:C++中的RTTI机制之typeid

简介:

RTTI,Runtime Type Information,即运行时类型信息,它提供了运行时确定对象类型的方法。

通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型。c++通过下面两个操作符提供RTTI。
(1)typeid:返回指针或引用所指对象的实际类型。
(2)dynamic_cast:将基类类型的指针或引用安全的转换为派生类型的指针或引用。
对于带虚函数的类,在运行时执行RTTI操作符,返回动态类型信息;对于其他类型,在编译时执行RTTI,返回静态类型信息。

上以节中,已经介绍了dynamic_cast的用法,本节主要来看typeid的用法。

 数据类型转换系列文章:

C++中的动态强制dynamic_cast

C++中的RTTI机制之typeid

C++中的静态强制static_cast

C++中的reinterpret_cast数据类型转换

C++中的const_cast数据类型转换

typeid的使用举例:

代码例子1:typeid用在普通类型

#include <iostream>
#include <typeinfo>
using namespace std;



int main()
{
     short s1 = 5;
     unsigned ui1 = 20;
     int i1 = 50, i2 = 100;
     char ch1 = 'a';
     wchar_t wch1 = L'b';
     float f1 = 3.14159265f;

     cout<<"typeid name:"<<endl;

     cout<<typeid(s1).name()<<endl;    // s
     cout<<typeid(ui1).name()<<endl;   // j
     cout<<typeid(i1).name()<<endl;    // i
     cout<<typeid(ch1).name()<<endl;   // c
     cout<<typeid(wch1).name()<<endl;  // w
     cout<<typeid(f1).name()<<endl;    // f
     
     cout<<"typeid compare result:"<<endl;

     if (typeid(i1) == typeid(i1)) {
          cout<<"typeid(i1) == typeid(i2)"<<endl; //执行到这个语句(类型相等)
     }else {
          cout<<"typeid(i1) != typeid(i1)"<<endl; 
     }

     if (typeid(s1) == typeid(i1)) {
          cout<<"typeid(s1) == typeid(i1)"<<endl;
     }else {
          cout<<"typeid(s1) != typeid(i1)"<<endl; //执行到这个语句(类型不相等)
     }

     return 0;
}
/*
编译环境:mac os下用g++编译:
MacBook-Pro cpp_stu % g++ typeid_test1.cpp
*/

代码例子2:typeid用在类类型

1) 

#include <iostream>
#include <typeinfo>
using namespace std;

class Base {
public:
    int a;
    virtual void fun1() {cout<<"Base::fun1"<<endl;}
    virtual void fun2() {cout<<"Base::fun2"<<endl;}
    virtual void fun3() {cout<<"Base::fun3"<<endl;}
};

class A {
public:
    int a;
    
};

class Derive : public Base{
public:
    int b;
    void fun2() {cout<<"Derive::fun2"<<endl;}
};

int main()
{
    
     Base b;
     Derive d;
     A a;

     cout<<typeid(b).name()<<endl; // 4Base
     cout<<typeid(d).name()<<endl; // 6Derive
     cout<<typeid(a).name()<<endl; // 1A
     
     cout<<"compare result:"<<endl;

     if (typeid(b) == typeid(d)) {
          cout<<"typeid(b) == typeid(d)"<<endl;
     }else {
          cout<<"typeid(b) != typeid(d)"<<endl; //执行到这个语句
     }

     return 0;
}
/*
编译环境:mac os下用g++编译:
MacBook-Pro cpp_stu % g++ typeid_test2.cpp
*/

运行结果:

4Base

6Derive

1A

compare result:

typeid(b) != typeid(d)

分析:

2)

再看下面的代码:

     Derive d;
     Derive *pD = new Derive();

     cout<<typeid(pD).name()<<endl; // P6Derive

     if (typeid(d) == typeid(pD)) {
          cout<<"typeid(d) == typeid(pD)"<<endl;
     }else {
          cout<<"typeid(pD) != typeid(pD)"<<endl; //执行到这个语句
     }

显然,pD是指针类型,typeid(pD).name()的结果是P6Derive,而不是6Derive。

3)

再看一个例子,把上面的

Derive *pD = new Derive();

改为:

Base *pB = new Derive();, 如下:

     Derive d;
     Base *pB = new Derive();

     cout<<typeid(pB).name()<<endl; // P4Base
     cout<<typeid(*pB).name()<<endl; // 6Derive
     
     cout<<"compare result:"<<endl;

     if (typeid(d) == typeid(*pB)) {
          cout<<"typeid(d) == typeid(*pB)"<<endl; //执行到这个语句
     }else {
          cout<<"typeid(pD) != typeid(*pB)"<<endl; 
     }

运行结果:

P4Base

6Derive

compare result:

typeid(d) == typeid(*pB)

分析:

d和 *pB的类型一样,都是Derive类型。

4)

上面的例子中,Base是虚基类(有虚函数),现在如果我们把Base改为非虚基类,看看typeid的结果如何。代码如下:

#include <iostream>
#include <typeinfo>
using namespace std;

class Base {
public:
    int a;
    void fun1() {cout<<"Base::fun1"<<endl;}
    void fun2() {cout<<"Base::fun2"<<endl;}
    void fun3() {cout<<"Base::fun3"<<endl;}
};

class Derive : public Base{
public:
    int b;
    void fun2() {cout<<"Derive::fun2"<<endl;}
};

int main()
{

     Derive d;
     Base *pB = new Derive();

     cout<<typeid(pB).name()<<endl;  // P4Base
     cout<<typeid(*pB).name()<<endl; // 4Base
     
     cout<<"compare result:"<<endl;

     if (typeid(d) == typeid(*pB)) {
          cout<<"typeid(d) == typeid(*pB)"<<endl;
     }else {
          cout<<"typeid(pD) != typeid(*pB)"<<endl; //执行到这个语句
     }

     return 0;
}
/*
编译环境:mac os下用g++编译:
MacBook-Pro cpp_stu % g++ typeid_test3.cpp
*/

运行结果:

P4Base

4Base

compare result:

typeid(pD) != typeid(*pB)

分析:

Base *pB = new Derive();  

创建的是Derive实例,但是typeid(*p B)的结果是4Base类型,而我们期望的是真正创建的对象的类型,即Derive。

这就是没有将父类定义成虚基类(包含virtual函数)的弊端。


  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值