首页 > 代码库 > 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++中的类型识别