请选择 进入手机版 | 继续访问电脑版

三峡论坛

微信扫一扫 分享朋友圈

已有 8956 人浏览分享

开启左侧

C++ typeid关键字详解

[复制链接]
8956 0
(给CPP开辟者减星标,提拔C/C++妙技)
滥觞:JeanChenghttps://blog.csdn.net/gatieme/article/details/50947821

【导读】:本文次要引见C++怎样完成运转期间的范例判定,而且较为深化的会商了详细源码的完成,感爱好的同窗一同战小编进修吧。

以下是注释

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。

dynamic_cast许可运转时辰停止范例转换,从而使法式可以正在一个类条理构造中宁静天转化范例,取之相对应的另有一个非宁静的转换操纵符static_cast,由于那没有是本文的会商重面,以是那里没有再胪陈,感爱好的能够自止查阅材料。

typeid是C++的枢纽字之一,同等于sizeof那类的操纵符。typeid操纵符的返回成果是名为type_info的尺度库范例的工具的援用(正在头文件typeinfo中界说,稍后我们看一下vs战gcc库内里的源码),它的表达式有下图两种情势。


完成机造取利用本领

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>
namespacestd{
classtype_info  {public:
virtual ~type_info();    { return __name[0] == '*' ? __name + 1 : __name; }

boolbefore(const type_info& __arg) const    { return __name < __arg.__name; }
booloperator==(const type_info& __arg) const    { return __name == __arg.__name; }
booloperator!=(const type_info& __arg) const    { return !operator==(__arg); }
virtualbool __is_pointer_p() const;
virtualbool __is_function_p() const;
protected:constchar *__name;
explicittype_info(constchar *__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-类工具

classbase{public :voidm(){cout<<"base"<<endl;}};classderived :public base{public:voidm(){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-带实函数的基类

classbase{public :virtualvoidm(){cout<<"base"<<endl;}};classderived :public base{public:voidm(){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

classbad_typeid :public exception   {public:    bad_typeid () throw() { }
// This declaration is not useless:// http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118virtual ~bad_typeid() throw();
// See comment in eh_exception.cc.virtualconstchar* what()constthrow();  };} // namespace std



参照

【C++】typeinfo.h

C++中的typeid枢纽字

- EOF -

保举浏览  面击题目可跳转
1、C++模板之SFINAE战enable_if阐发

2、C++ 线程部分变量thread_local

3、C++ 智能指针用法详解

闭于 C++ typeid枢纽字,欢送正在批评中战我讨论。以为文章没有错,请面赞战正在看撑持我持续分享好文。感谢!

存眷『CPP开辟者』

看粗选C++手艺文章 . 减C++开辟者专属圈子

↓↓↓

面赞战正在看便是最年夜的撑持❤️
严正声明:上述帖子内容及图片只能代表作者或者网友分享的观点,并不能代表三峡论坛网站平台,三峡论坛网站只是一个公开开放的BBS社区,任何人都可以分享正能量的帖子,如有侵权的内容请及时联系我们,我们将会第一时间删除,封禁网友ID!

举报 使用道具

回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

0

关注

0

粉丝

1

主题
精彩推荐
热门资讯
网友晒图
图文推荐
  • 联系我们
  • 邮箱:928283588#qq.com(请把#改成@)
  • 电话:13242976199
  • QQ客服 928283588
  • 工作时间:周一至周五(早上9点至下午5点)
  • 微信公众平台

  • 扫描访问手机版

QQ|宜三峡论坛|宜三峡在线|Archiver|小黑屋|手机版|三峡论坛 ( 粤ICP备16085663号 )|网站地图|网站地图

GMT+8, 2021-3-3 03:35 , Processed in 0.338287 second(s), 35 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.