C++ typeid typename使用

來源:互聯網
上載者:User
類型標識符(typeid)

標準C++的一個新特徵是RTTI(Run-Time Type Information運行時類型資訊),它為程式在運行時確定物件類型,提供了一種標準方法。在標準C++中,有三個支援RTTI的元素:

<!--[if !supportLists]-->1.         <!--[endif]-->關鍵字dynamic_cast(動態強制轉換):操作符dynamic_cast將一個指向基類的指標轉換為一個指向衍生類別的指標(如果不能正確轉換,則返回0——null 指標),格式為:

dynamic_cast < type-id > ( exdivssion )

dynamic_cast在轉化過程中要用到相關類的類型資訊類type_info中的資訊。該關鍵字在前面的小小節1.2)中已經介紹過。

<!--[if !supportLists]-->2.         <!--[endif]-->關鍵字typeid(類型標識符):用來檢測指標類型(返回type_info類對象的指標),格式為:

typeid ( exdivssion ) 或 typeid ( type-id )

其中,exdivssion為結果為對象的運算式,type-id為類名。

<!--[if !supportLists]-->3.         <!--[endif]-->類type_info(類型資訊):儲存特定類型的有關資訊,定義在<typeinfo>標頭檔中。type_info類的具體內容由編譯器實現來決定,但是至少必須包含返回字串的name()成員函數。下面是type_info類的VC05實現版本:

class type_info { // VC05中定義的簡化

public:

    virtual ~type_info();

    bool operator==(const type_info& rhs) const;

    bool operator!=(const type_info& rhs) const;

    int before(const type_info& rhs) const;

    const char* name() const;

    const char* raw_name() const;

private:

    void *_m_data;

    char _m_d_name[1];

    type_info(const type_info& rhs);

    type_info& operator=(const type_info& rhs);

    static const char *_Name_base(const type_info *prhs, __type_info_node* __ptype_info_node);

    static void _Type_info_dtor(type_info *prhs);

};

例如:(可建立一個名為tmp的“Visual C++/常規/空項目”型項目,將如下兩個檔案加入到該項目中)

// tmp.h

template<class T> class A { };

 

// tmp.cpp

#include <typeinfo.h>

#include <iostream>

#include "tmp.h"

using namespace std;

 

int main( ){

       A<int> a;

       A<char> b;

       cout << typeid(a).name() << endl;

       cout << typeid(b).name() << endl;

       if (typeid(a) == typeid(b)) cout << "a==b" << endl;

       else cout << "a!=b" << endl << endl;

       cout << endl;

 

       int i;

       cout << typeid(int).name() << endl;

       cout << typeid(i).name() << endl;

       if (typeid(int) == typeid(i)) cout << "typeid(int) = typeid(i)" << endl;

       else cout << "typeid(int) != typeid(i)"<< endl;

       cout << endl;

}

 

輸出結果為:

class A<int>

class A<char>

a!=b

 

int

int

typeid(int) = typeid(i)

 

注意:只有對包含虛函數的抽象類別層次,使用RTTI才有實際意義。

8)類型名(typename)

對於有的嵌套類中的標識符,本來應該作為類型來處理,但是編譯器並不知道這一點,而可能把它當成了靜態變數。

對模板中出現的一個標識符,若編譯器既可以把它當作一個類型,又可以把它視為一個變數、對象、枚舉、函數或模板時,則編譯器一般不會認為這個標識符是類型,而認為它是一個其他元素(例如是變數或對象)。

解決辦法是,使用標準C++新增加的關鍵字typename,來明確告訴編譯器,它後面的標識符是一個類型名,而不是其他什麼東西。

例如:

template<class T> class X {

       typename T::id i; // 如果沒有typename來說明,編譯器會將T::id當成靜態變數

public:

       void f ( ) { i.g( ); }

};

class Y {

public:

       class id {

       public:

              void g( ) { }

       };

};

int main ( ) {

       X<Y> xy;

       xy.f ( );

}

最後一種用法是說,可以用typename來代替模板聲明中的型別參數class,即:可將

template<class T> ……

改為

template<typename T> ……

而且這樣更名符其實。因為除了類類型外,基礎資料型別 (Elementary Data Type)和結構等類型,也是可以作為模板的型別參數的。

例如:(能夠列印任意標準C++序列容器中的資料的函數模板)

// PrintSeq.cpp

#include <iostream>

#include <list>

#include <memory>

#include <vector>

using namespace std;

 

template<class T, template<class U, class = allocator<U> > class Seq>

void printSeq(Seq<T>& seq) {

       for (typename Seq<T>::iterator b = seq.begin(); b != seq.end(); b++)

              cout << *b << endl;

}

 

int main ( ) {

       // 處理向量

       vector<int> v;

       v.push_back(1);  v.push_back(2);

       printSeq(v);

       // 處理表

       list<int> lst;

       lst.push_back(3);         lst.push_back(4);

       printSeq(lst);

}

輸出為:

1

2

3

4

注意:關鍵字typename並不能建立一個新類型名,它只是通知編譯器,將標識符解釋為類型。若想建立一個新類型名,你可以使用關鍵字typedef。例如

typename Seq<T>::iterator It; // 告訴編譯器iterator是類型,It是該類型的變數

typedef typename Seq<T>::iterator It; // 建立了一個與iterator等價的新類型名It

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.