首页 > 代码库 > C++中的类型识别

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 ~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 = 类型名;

 

C++中的类型识别