中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

typeid關鍵字如何在c++中使用

發布時間:2020-11-12 15:04:42 來源:億速云 閱讀:143 作者:Leah 欄目:開發技術

這篇文章將為大家詳細講解有關 typeid關鍵字如何在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來查找源碼

typeid關鍵字如何在c++中使用

#ifndef _TYPEINFO
#define _TYPEINFO

#include <exception>

namespace std
{

 class type_info
 {
 public:

  virtual ~type_info();
  { return __name[0] == '*' &#63; __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

typeid關鍵字如何在c++中使用

關于 typeid關鍵字如何在c++中使用就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

自治县| 洛川县| 调兵山市| 桓仁| 玛多县| 德清县| 南投市| 涿鹿县| 清涧县| 虞城县| 桓仁| 黎平县| 保德县| 泾阳县| 和龙市| 普定县| 高邑县| 靖江市| 富民县| 南召县| 隆昌县| 永和县| 康平县| 北安市| 井陉县| 临洮县| 乐山市| 桐柏县| 阿拉善左旗| 体育| 白银市| 渭南市| 陇西县| 新兴县| 临泉县| 黔南| 曲周县| 宜良县| 渝中区| 滨州市| 墨江|