C++ typeid关键字详解
typeid关键字注意:typeid是操作符,不是函数。这点与sizeof类似) 运行时获知变量类型名称,可以使用 typeid(变量).name() 需要注意不是所有编译器都输出”int”、”float”等之类的名称,对于这类的编译器可以这样使用 1 int ia = 3;
2 if(typeid(ia) == typeid(int))
3 {
4 cout <<"int" <<endl;
5 }
? RTTI(Run-Time Type Identification)-运行时类型识别在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。 在C++中,为了支持RTTI提供了两个操作符:
实现机制与使用技巧type_info类对象类别判别对象类别判别分析如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算; ISO C++标准并没有确切定义
type_info类提供了public虚 析构函数,以使用户能够用其作为基类。它的默认构造函数和拷贝构造函数及赋值操作符都定义为private,所以不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符(由此可见,如果把typeid看作函数的话,其应该是type_info的 友元)。type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此,见后面的程序),这具体由编译器的实现所决定的,标准只要求实现为每个类型返回唯一的字符串。 type_info类源代码使用 1 #ifndef _TYPEINFO
2 #define _TYPEINFO
3
4 #include <exception>
5
6 namespace std
7 8
9 class type_info
10 {
11 public:
12
13 virtual ~type_info();
14 { return __name[0] == '*' ? __name + 1 : __name; }
15
16
17 bool before(const type_info& __arg) const
18 { return __name < __arg.__name; }
19
20 bool operator==(21 { return __name ==22
23 operator!=(24 { return !operator==(__arg); }
25
26 virtual bool __is_pointer_p() const27
28 bool __is_function_p() 29
30 protected31 const char *__name;
32
33 explicit type_info(__n): __name(__n) { }
34
35 private36 type_info& operator=(const type_info&);
37 type_info(38 };
39
40 } // extern "C++"
41 #endif
示例1-基本数据类型下表列出了使用typeid操作符的表达式的值 a;
double b;
c;
4 long d;
?
操作符typeid返回的是一个type_info类(用于描述数据类型的一个系统类)对象的引用。这个操作符可以用于表达式和类型名(包括自定的数据类型,比如类)。 示例2-类对象class base
3 :
4 void m(){cout<<base"<<endl;}
5 };
class derived : public 8 9 derived10 };
?假设我们根据例2中定义的两个类来定义如下指针: base * p = new derived;
下表将给出使用typeid操作符的结果。
对于表达式typeid(p),同样,因为p是base*类型的指针,因此typeid(p) == typeid(base*)为真,而typeid(p) == typeid(derived*)为假。而对于表达式typeid(*p),由于此时的基类不具有多态性,因而*p将会采用编译期类型来计算,编译期*p是base对象,因此表达式typeid(*p) == typeid(derived)为假,typeid(*p) == typeid(base)为真。 示例3-带虚函数的基类10 };
假设我们如本例所示定义了两个类base类和derived类,基于这两个类定义,我们定义指针如下: new derived;
下表将给出使用typeid操作符的结果。
对于表达式typeid(p),因为p是base*类型的指针,因此typeid(p) == typeid(base*)为真,而typeid(p) == typeid(derived*)为假。而对于表达式typeid(*p),因为base类具有多态性,因而在计算typeid(*p)时会根据运行时p所指向的实际类型去计算,而本例中p指向的是派生类对象,因此表达式typeid(*p) == typeid(derived)为真,typeid(*p) == typeid(base)为假。 异常处理bad_typeid 1 class bad_typeid : exception
3 4 bad_typeid () throw() { }
6 This declaration is not useless:
7 // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
8 virtual ~bad_typeid() ();
9
10 See comment in eh_exception.cc.
11 char* what() 12 13 } namespace std
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |