欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

VS2008附帶的type_info類只有頭文件,沒有源文件,聲明如下:

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 *);
};

測試代碼:

#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

在解釋每個函數(shù)的實現(xiàn)原理前先開看type_info類的存儲方式。

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

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

編譯器會為每一種typeid操作的類型生成一份保存在數(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那一行下斷點,查看到p的值為:

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

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

每種類型的type_info數(shù)據(jù)長度依賴于類型名稱,至少9個字節(jié)。

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

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

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

讀者可能會有兩點疑惑:

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

備注:C++并沒有規(guī)定typeid實現(xiàn)標準,各個編譯器可能會不一樣,上述分析過程基于VS2008自帶的編譯器。

總結(jié):typeid帶來的時間和空間開銷是非常小的,不過使用的時候盡量不要違背開放封閉原則。

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

相關(guān)文章

  • C語言實現(xiàn)一個多線程委托模型的示例詳解

    C語言實現(xiàn)一個多線程委托模型的示例詳解

    這篇文章主要介紹了C語言實現(xiàn)一個多線程委托模型,這就是一個使用C語言實現(xiàn)多線程委托模型的例子,其中包含boss線程和worker線程,可以處理工作線程的異常情況,需要的朋友可以參考下
    2023-06-06
  • C語言簡單實現(xiàn)門禁系統(tǒng)

    C語言簡單實現(xiàn)門禁系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言簡單實現(xiàn)門禁系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • C語言實現(xiàn)宿舍管理課程設(shè)計

    C語言實現(xiàn)宿舍管理課程設(shè)計

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)宿舍管理課程設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Opencv透視變換綜合實例詳解

    Opencv透視變換綜合實例詳解

    這篇文章主要為大家詳細介紹了Opencv透視變換綜合實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • VSCode 搭建 Arm 遠程調(diào)試環(huán)境的步驟詳解

    VSCode 搭建 Arm 遠程調(diào)試環(huán)境的步驟詳解

    這篇文章主要介紹了VSCode 搭建 Arm 遠程調(diào)試環(huán)境的步驟詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-04-04
  • C語言高斯消元法的使用詳解

    C語言高斯消元法的使用詳解

    本篇文章是對C語言中高斯消元法的使用進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • C++深入學(xué)習之徹底理清重載函數(shù)匹配

    C++深入學(xué)習之徹底理清重載函數(shù)匹配

    C++ 不允許變量重名,但是允許多個函數(shù)取相同的名字,只要參數(shù)表不同即可,這叫作函數(shù)的重載,下面這篇文章主要給大家介紹了關(guān)于C++深入學(xué)習之徹底理清重載函數(shù)匹配的相關(guān)資料,需要的朋友可以參考下
    2019-01-01
  • Qt與QWebEngineView交互完整參考示例代碼

    Qt與QWebEngineView交互完整參考示例代碼

    QWebEngineView是Qt框架中的一個組件,它是基于Chromium內(nèi)核的Web瀏覽器引擎,用于在Qt應(yīng)用程序中嵌入網(wǎng)頁內(nèi)容和實現(xiàn)各種Web應(yīng)用功能,這篇文章主要給大家介紹了關(guān)于Qt與QWebEngineView交互完整參考的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • C語言如何實現(xiàn)三子棋

    C語言如何實現(xiàn)三子棋

    這篇文章主要介紹了C語言如何實現(xiàn)三子棋問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • VC++?2019?"const?char*"類型的實參與"LPCTSTR"類型的形參不兼容解決

    VC++?2019?"const?char*"類型的實參與"LPCTSTR"

    這篇文章主要給大家介紹了關(guān)于VC++?2019?"const?char*"類型的實參與"LPCTSTR"類型的形參不兼容的解決方法,文中通過圖文介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2023-03-03

最新評論