最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中typeid實(shí)現(xiàn)原理詳解

 更新時(shí)間:2020年11月11日 11:24:28   作者:passion_wu128  
這篇文章主要給大家介紹了關(guān)于C++中typeid實(shí)現(xiàn)原理的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

最近看了boost::any類(lèi)源碼,其實(shí)現(xiàn)主要依賴(lài)typeid操作符。很好奇這樣實(shí)現(xiàn)的時(shí)間和空間開(kāi)銷(xiāo)有多大,決定探一下究竟。

VS2008附帶的type_info類(lèi)只有頭文件,沒(méi)有源文件,聲明如下:

class type_info {
public:
 virtual ~type_info();
 _CRTIMP_PURE bool __CLR_OR_THIS_CALL operator==(const type_info& rhs) const;
 _CRTIMP_PURE bool __CLR_OR_THIS_CALL operator!=(const type_info& rhs) const;
 _CRTIMP_PURE int __CLR_OR_THIS_CALL before(const type_info& rhs) const;
 _CRTIMP_PURE const char* __CLR_OR_THIS_CALL name(__type_info_node* __ptype_info_node = &__type_info_root_node) const;
 _CRTIMP_PURE const char* __CLR_OR_THIS_CALL raw_name() const;
private:
 void *_m_data;
 char _m_d_name[1];
 __CLR_OR_THIS_CALL type_info(const type_info& rhs);
 type_info& __CLR_OR_THIS_CALL operator=(const type_info& rhs);
 _CRTIMP_PURE static const char *__CLRCALL_OR_CDECL _Name_base(const type_info *,__type_info_node* __ptype_info_node);
 _CRTIMP_PURE static void __CLRCALL_OR_CDECL _Type_info_dtor(type_info *);
};

測(cè)試代碼:

#include <iostream>
using namespace std;
 
class Object
{
};
 
int main()
{
	Object obj;
	cout << "type name:" << typeid(obj).name() << endl;
	cout << "type raw name:" << typeid(obj).raw_name() << endl;
	if(typeid(obj) == typeid(Object))
	{
		cout << "type is equal" << endl;
	}
	else
	{
		cout << "type is not equal" << endl;
	}
	return 0;
}

輸出:

type name:class Object
type raw name:.?AVObject@@
type is equal

在解釋每個(gè)函數(shù)的實(shí)現(xiàn)原理前先開(kāi)看type_info類(lèi)的存儲(chǔ)方式。

typeid返回的是type_info的引用,這個(gè)類(lèi)不能拷貝,也不能自己構(gòu)造,所以每個(gè)類(lèi)最多只有一個(gè)type_info的數(shù)據(jù),這個(gè)數(shù)據(jù)存放在哪里的呢?

用UltraEdit打開(kāi)exe文件,搜索“Object”,能找到這個(gè)字符串。再用PE工具打開(kāi)這個(gè)exe,發(fā)現(xiàn)這個(gè)字符串屬于data節(jié)(這是可讀可寫(xiě)的全局?jǐn)?shù)據(jù)段)。再把有typeid的代碼都注釋?zhuān)琍E文件中沒(méi)有了這個(gè)字符串。得出一個(gè)結(jié)論:

編譯器會(huì)為每一種typeid操作的類(lèi)型生成一份保存在數(shù)據(jù)段的type_info數(shù)據(jù)。

這份數(shù)據(jù)有多大呢?看下面這段代碼:

#include <iostream>
using namespace std;
 
class Object
{
};
 
int main()
{
	const type_info* p = &typeid(Object);
	cout << p << endl;
	return 0;
}

在cout那一行下斷點(diǎn),查看到p的值為:

再看下這個(gè)類(lèi)的聲明,析構(gòu)函數(shù)為virtual類(lèi)型的,所以p的頭四字節(jié)為虛函數(shù)表。p+4為_(kāi)m_data,void*類(lèi)型,四個(gè)字節(jié),調(diào)試時(shí)發(fā)現(xiàn)都是0,還不清楚其表示什么。

p+8為_(kāi)m_d_name,char類(lèi)型數(shù)組,存儲(chǔ)的是raw_name,每種類(lèi)型的raw_name大小不定長(zhǎng),所以數(shù)組長(zhǎng)度為1?,F(xiàn)在type_info的存儲(chǔ)結(jié)構(gòu)已經(jīng)一目了然:

每種類(lèi)型的type_info數(shù)據(jù)長(zhǎng)度依賴(lài)于類(lèi)型名稱(chēng),至少9個(gè)字節(jié)。

現(xiàn)在假設(shè)一個(gè)復(fù)雜的工程里面有50個(gè)類(lèi)型用了typeid操作符,平均每個(gè)type_info長(zhǎng)度為24,這些數(shù)據(jù)增加的PE大小為1200B,就1K左右。而現(xiàn)在的PE動(dòng)輒幾十M,所以這點(diǎn)空間開(kāi)銷(xiāo)根本不算什么。

再看看這些函數(shù)調(diào)用的開(kāi)銷(xiāo):

  • raw_name函數(shù)直接返回_m_d_name的地址,非???;
  • name函數(shù)將_m_d_name存儲(chǔ)的字符串解碼成實(shí)際的名稱(chēng),也是很快;
  • ==操作符是比較raw_name是否相等,也是很快。

讀者可能會(huì)有兩點(diǎn)疑惑:

  1. 存儲(chǔ)的時(shí)候?yàn)槭裁床恢苯哟鎯?chǔ)成name呢?我想最大的原因是節(jié)省空間,比如double的raw_name為".N",name為"double"多了四字節(jié)。
  2. ==操作符為什么不直接比較兩個(gè)type_info引用的地址是否相等呢?我也很疑惑,我看匯編碼發(fā)現(xiàn)它是比較raw_name。

備注:C++并沒(méi)有規(guī)定typeid實(shí)現(xiàn)標(biāo)準(zhǔn),各個(gè)編譯器可能會(huì)不一樣,上述分析過(guò)程基于VS2008自帶的編譯器。

總結(jié):typeid帶來(lái)的時(shí)間和空間開(kāi)銷(xiāo)是非常小的,不過(guò)使用的時(shí)候盡量不要違背開(kāi)放封閉原則。

到此這篇關(guān)于C++中typeid實(shí)現(xiàn)原理的文章就介紹到這了,更多相關(guān)C++ typeid實(shí)現(xiàn)原理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)課程設(shè)計(jì)word版

    C語(yǔ)言學(xué)生成績(jī)管理系統(tǒng)課程設(shè)計(jì)word版

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言學(xué)生成績(jī)管理課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • VC++中的字體設(shè)置方法詳解

    VC++中的字體設(shè)置方法詳解

    以下是對(duì)VC++中的字體設(shè)置方法進(jìn)行了詳細(xì)的介紹,需要的朋友可以過(guò)來(lái)參考下
    2013-09-09
  • 詳解C++中vector的理解以及模擬實(shí)現(xiàn)

    詳解C++中vector的理解以及模擬實(shí)現(xiàn)

    vector是表示可變大小數(shù)組的序列容器。這篇文章主要為大家詳細(xì)介紹了vector的理解以及模擬實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-03-03
  • 簡(jiǎn)單解讀C++中的虛函數(shù)

    簡(jiǎn)單解讀C++中的虛函數(shù)

    這篇文章主要介紹了C++中的虛函數(shù),在C++中,虛函數(shù)聯(lián)系到多態(tài)、多態(tài)聯(lián)系到繼承,因而虛函數(shù)是C++中的一大重要特性,需要的朋友可以參考下
    2016-04-04
  • Windows上CLion的配置步驟詳解

    Windows上CLion的配置步驟詳解

    這篇文章主要介紹了Windows上CLion的配置,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-11-11
  • C語(yǔ)言關(guān)鍵字const和指針的結(jié)合使用

    C語(yǔ)言關(guān)鍵字const和指針的結(jié)合使用

    這篇文章主要介紹了C語(yǔ)言關(guān)鍵字const和指針的結(jié)合,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 如何利用Matlab繪制出好看的火山圖

    如何利用Matlab繪制出好看的火山圖

    火山圖是散點(diǎn)圖的一種,它將統(tǒng)計(jì)測(cè)試中的統(tǒng)計(jì)顯著性量度和變化幅度相結(jié)合,從而能夠幫助快速直觀地識(shí)別那些變化幅度較大且具有統(tǒng)計(jì)學(xué)意義的數(shù)據(jù)點(diǎn)。本文將通過(guò)Matlab繪制好看的火山圖,需要的可以參考一下
    2022-03-03
  • C++實(shí)現(xiàn)延遲的方法詳解

    C++實(shí)現(xiàn)延遲的方法詳解

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)延遲的三個(gè)方法,文中的示例代碼講解詳細(xì),對(duì)我們深入了解C++有一定的幫助,感興趣的小伙伴可以學(xué)習(xí)一下
    2022-12-12
  • c++中.dll與.lib文件的生成與使用的詳解

    c++中.dll與.lib文件的生成與使用的詳解

    本篇文章介紹了,在c++中.dll與.lib文件的生成與使用的詳細(xì)介紹,需要的朋友參考下
    2013-05-05
  • 雙向鏈表插入刪除基本應(yīng)用介紹

    雙向鏈表插入刪除基本應(yīng)用介紹

    本文將詳細(xì)介紹建立雙向鏈表,實(shí)現(xiàn)對(duì)雙向鏈表的插入,刪除操作,需要了解的朋友可以參考下
    2012-11-11

最新評(píng)論

望都县| 青河县| 平南县| 文山县| 土默特左旗| 万州区| 溆浦县| 肃北| 新平| 巫山县| 鄂伦春自治旗| 奇台县| 宣威市| 靖边县| 双峰县| 宁化县| 仁布县| 太湖县| 吉安市| 安塞县| 宜章县| 天门市| 昌宁县| 乌兰浩特市| 长沙市| 南陵县| 铜鼓县| 墨竹工卡县| 平遥县| 永安市| 乌鲁木齐市| 开平市| 右玉县| 介休市| 海晏县| 闽侯县| 清水河县| 德州市| 黎平县| 来安县| 九台市|