时间:2021-05-20
typeid关键字
注意:typeid是操作符,不是函数。这点与sizeof类似)
运行时获知变量类型名称,可以使用 typeid(变量).name()
需要注意不是所有编译器都输出”int”、”float”等之类的名称,对于这类的编译器可以这样使用
int ia = 3; if(typeid(ia) == typeid(int)) { cout <<"int" <<endl; }RTTI(Run-Time Type Identification)-运行时类型识别
在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型。
在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和typeid
实现机制与使用技巧
type_info类对象类别判别
对象类别判别分析
如果表达式的类型是类类型且至少包含有一个虚函数,则typeid操作符返回表达式的动态类型,需要在运行时计算;
否则,typeid操作符返回表达式的静态类型,在编译时就可以计算。
ISO C++标准并没有确切定义type_info,它的确切定义编译器相关的,但是标准却规定了其实现必需提供如下四种操作(在之后的章节中我会来分析type_info类文件的源码)
运算 描述 t1 == t2 如果两个对象t1和t2类型相同,则返回true;否则返回false t1 != t2 如果两个对象t1和t2类型不同,则返回true;否则返回false t.name() 返回类型的C-style字符串,类型名字用系统相关的方法产生1 t1.before(t2) 返回指出t1是否出现在t2之前的bool值
type_info类提供了public虚 析构函数,以使用户能够用其作为基类。它的默认构造函数和拷贝构造函数及赋值操作符都定义为private,所以不能定义或复制type_info类型的对象。程序中创建type_info对象的唯一方法是使用typeid操作符(由此可见,如果把typeid看作函数的话,其应该是type_info的 友元)。type_info的name成员函数返回C-style的字符串,用来表示相应的类型名,但务必注意这个返回的类型名与程序中使用的相应类型名并不一定一致(往往如此,见后面的程序),这具体由编译器的实现所决定的,标准只要求实现为每个类型返回唯一的字符串。
type_info类源代码
使用sudo find / -name typeinfo.h来查找源码
#ifndef _TYPEINFO#define _TYPEINFO#include <exception>namespace std{ class type_info { public: virtual ~type_info(); { return __name[0] == '*' ? __name + 1 : __name; } bool before(const type_info& __arg) const { return __name < __arg.__name; } bool operator==(const type_info& __arg) const { return __name == __arg.__name; } bool operator!=(const type_info& __arg) const { return !operator==(__arg); } virtual bool __is_pointer_p() const; virtual bool __is_function_p() const; protected: const char *__name; explicit type_info(const char *__n): __name(__n) { } private: type_info& operator=(const type_info&); type_info(const type_info&); };} // extern "C++"#endif示例1-基本数据类型
下表列出了使用typeid操作符的表达式的值
int a; double b; char * c; long d;运算 描述 typeid(a) == typeid(int) true typeid(a) == typeid(float) false typeid(a) == typeid(int *) false typeid(b) == typeid(double) true typeid(b) == typeid(float) false typeid(b) == typeid(long double) false typeid(c) == typeid(char *) true typeid(c) == typeid(char) false typeid(c) == typeid(string) false typeid(d) == typeid(long) true typeid(d) == typeid(int) false
操作符typeid返回的是一个type_info类(用于描述数据类型的一个系统类)对象的引用。这个操作符可以用于表达式和类型名(包括自定的数据类型,比如类)。
示例2-类对象
class base{public : void m(){cout<<"base"<<endl;}};class derived : public base{public: void m(){cout<<"derived"<<endl;}};假设我们根据例2中定义的两个类来定义如下指针:
base * p = new derived;下表将给出使用typeid操作符的结果。
运算 描述 typeid(p) == typeid(base*) true typeid(p) == typeid(derived*) false typeid(*p) == typeid(base) true typeid(*p) == typeid(derived) false
对于表达式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-带虚函数的基类
class base{public : virtual void m(){cout<<"base"<<endl;}};class derived : public base{public: void m(){cout<<"derived"<<endl;}};假设我们如本例所示定义了两个类base类和derived类,基于这两个类定义,我们定义指针如下:
base * p = new derived;下表将给出使用typeid操作符的结果。
运算 描述 typeid(p) == typeid(base*) true typeid(p) == typeid(derived*) false typeid(*p) == typeid(base) false typeid(*p) == typeid(derived) true
对于表达式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
class bad_typeid : public exception { public: bad_typeid () throw() { } // This declaration is not useless: // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118 virtual ~bad_typeid() throw(); // See comment in eh_exception.cc. virtual const char* what() const throw(); };} // namespace std以上就是c++ typeid关键字的使用的详细内容,更多关于c++ typeid关键字的资料请关注其它相关文章!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
Java的static关键字和C/C++语言的关键字有所不同:一旦在Java里使用了static关键字,那么这样的内容不再属于对象自己,而是属于类本身的,所以凡
前言近期看到C++标准中对volatile关键字的定义,发现和java的volatile关键字完全不一样,C++的volatile对并发编程基本没有帮助。网上也
问题描述:C++里面为什么有时候在函数声明的时候在后面加throw()关键字?解释:C++函数后面加关键字throw(something)限制,是对这个函数的异
AutoTypeDeduction自动类型推导auto关键字让用户得以使用C++内置的类型推导特性。std::stringsomething=something
1,new关键字和malloc函数区别(自己、功能、应用):1,new关键字是C++的一部分:1,如果是C++编译器,则肯定可以用new申请堆空间内存;2,ma