C++中的类型识别

                                                                                                                                                                                     文章参考“狄泰视频”

在面向对象中可能出现下面的情况:

  --基类指针指向子类对象

  --基类引用,成为子类对象的别名

Base* p = new Derived();

Base& r = *p;

这里涉及动态类型和静态类型;

静态类型:变量(对象)自身的类型

动态类型:指针(引用)所指向的对象的实际类型

 

 

void test(Base* b)

{

  Derived* d = static_cast<Derived*>(b);//危险的类型转换

}

这里的基类指针是否可以强制转换为子类指针,取决于指针实际指向的类型;因为多态的性质,子类是特殊的父类;

C++中如何得到动态类型呢?

解决方案有两个:

1.利用多态。手工在类中定义一个 虚函数 type()用于返回指针类型;子类重写虚函数;

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Base
 7 {
 8 public:
 9     virtual string type()
10     {
11         return "Base";
12     }
13 };
14 
15 class Derived : public Base
16 {
17 public:
18     string type()
19     {
20         return "Derived";
21     }
22     
23     void printf()
24     {
25         cout << "I'm a Derived." << endl;
26     }
27 };
28 
29 class Child : public Base
30 {
31 public:
32     string type()
33     {
34         return "Child";
35     }
36 };
37 
38 void test(Base* b)
39 {
40     /* 危险的转换方式 */
41     // Derived* d = static_cast<Derived*>(b);
42     
43     if( b->type() == "Derived" )
44     {
45         Derived* d = static_cast<Derived*>(b);
46         
47         d->printf();
48     }
49     
50     // cout << dynamic_cast<Derived*>(b) << endl;
51 }
52 
53 
54 int main(int argc, char *argv[])
55 {
56     Base b;
57     Derived d;
58     Child c;
59     
60     test(&b);
61     test(&d);
62     test(&c);
63     
64     return 0;
65 }

2.第一种方法复杂麻烦容易遗漏;现在介绍第二种方法:

c++提供了关键字typeid用于获取类型信息

typeid 返回对应参数的类型信息

typeid 返回一个type_info 类对象

typeid不能为空否则抛异常

当参数为类型时:返回静态类型信息

当参数为变量时:

--不存在虚函数表-返回静态类型信息

--存在虚函数表-返回动态类型信息

--即当有多态产生的时候才会根据实际代表的类型进行返回

例:

#include <iostream>
#include <string>
#include <typeinfo> //使用typeid需要包含typeinfo头文件

using namespace std;

class Base
{
public:
virtual void printf()
{
  cout<<"I am a Base."<<endl;
} virtual ~Base() { } }; class Derived : public Base { public: void printf() { cout<<"I am a Derived."<<endl; } }; void test(Base* b) { const type_info& tb = typeid(*b); cout << tb.name() <<endl; } int main() { int i = 0; const type_info& tiv = typeid(i); const type_info& tii = typeid(int); cout << (tiv == tii) << endl; Base b; Derived d; test(&b); test(&d); return 0; }

 输出结果:

值得注意的是 typeid中返回的type_info.name 中的类型名在各个编译器当中并不一样,所以并不能令其type_info.name = 类型名;

 

转载于:https://www.cnblogs.com/sunxiaolongblog/p/6682823.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值