程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 自定義類型的思考

自定義類型的思考

編輯:C++入門知識

最近在群裡面看到這樣一個語句:typedef typename T::value_type _type; 我的第一反應這是一個自定義類型,沒錯確實是一句自定義類型,但這和我們平常見到的自定義類型又有不同,T::value_type 這塊會讓大多數人和很不解。其實他的意義就是:這個T必須含有value_type這個成員,也就是說T必須是個類或者命名空間,如果還不明白繼續往下看。

[cpp]
// 自定義類型1-這是常規自定義類型的變形,首先傳入的classType應該是個類且必須有value_type這個成員,例如STL中的類. 
template<class classType,class keyType = int,class valueType = char*> 
struct CCustomType 

    typedef typename classType::value_type custom_type; 
    custom_type data; 
};  

使用CCustomType自定義類型:
[cpp] 
CCustomType<string>   string_; 
string_.data = 'c';                     // string::value_type 是char 類型,從下面的basic_string就可以看出 
 
CCustomType<basic_string<char,char_traits<char>,allocator<char>>>   string_2; 
string_2.data = 'x';                        // char 
 
CCustomType<list<char*>>    list_; 
list_.data = "you are so beautiful";                // char* 
 
CCustomType<set<UINT>>  set_; 
set_.data = 512139461;                      //  UINT 

聲明CCustomType<map<int,char*>,int,char*> pair_;
這裡pair_.data 是map的成員value_type也就是pair類型,更具體的講是pair<int,char*> #
在使用CCustomType<map<int,char*>,int,char*>之前,我們先看下stl中pair的用法:
[cpp]
std::pair<int,char*> pair_1(2012,"hello world");      // 利用構造函數初始化pair_1 
// 
std::pair<int,char*> pair_2; 
pair_2 = make_pair(1989,(char*)"hansen");           // ok make_pair賦值 
// 
pair_2.first = 2000;                        // ok  
pair_2.second = "just test";                    // ok 
// 
map<int,char*> nMap; 
nMap.insert(pair_1);                                 
nMap.insert(pair_2);                         
 
CCustomType<map<int,char*>,int,char*> pair_;// ok map應該這樣用,key是int型 ,value是char*類型 
//(pair_.data).first = 2012; error C3892: “pair_”: 不能給常量賦. 
//通過監視查看pair_.data.first是個const int類型為什麼會變成const int,我傳入的是<int,char*>類型,應該是pair<int,char*>類型,開始我也有這個疑問. 
(pair_.data).second = "that's ok";          // ok,value不是const的,可以賦值 

分析:
[cpp]
//按照上面的原型,聲明一個pair類型變量 pair_test 
map<int,char*>::value_type pair_test(2013,"test test"); 
 
// 通過源碼一步步跟進查看這個map的value_type,first:const int ,second:char* 
// 1.map的value_type來自_Mybase的成員value_type: 
typedef typename _Mybase::value_type value_type; 
// 2.繼續跟發現_Mybase是個模板類,由_Tmap_traits構造: 
typedef _Tree<_Tmap_traits<_Kty, _Ty, _Pr, _Alloc, false> > _Mybase; 
// 3.就要揭曉答案了,跟_Tmap_traits發現原來他自定義了pair類型: 
typedef pair<const _Kty, _Ty> value_type; 
// 4.這就是為什麼map的key是個const類型,也表明上面的自定義類型CCustomType的data成員實際上是個pair<const T,T> 

那麼有什麼辦法可以給自定義類型CCustomType的data成員賦值呢,答案是通過構造函數,我們先對CCustomType做下變形:
[cpp] 
template<class classType,class keyType = int,class valueType = char*> 
struct CCustomTypeEx 

    typedef typename classType::value_type custom_type;          
    custom_type data; 
    CCustomTypeEx() {} 
    CCustomTypeEx(keyType _key,valueType _value) 
        :data(_key,_value)                  // 調用classType::pair的構造函數 
    { 
    } 
 
}; www.2cto.com
[cpp] 
CCustomTypeEx<map<int,char*>,int,char*> pair_ex(1989,"hansen");     // ok 

總結:關於CCustomType<map,int,char*> pair_那個問題,其實在一開始我就偷換掉了概念,前面有句打#的就是理解不完全,死死認定pair_.data是個pair類型堅信pair是可以在構造後賦值的,沒錯常規的pair確實可以這樣做,但我忘記了CCustomType中關鍵的一句typedef typename classType::value_type custom_type;也就是說這個value_type一定要是classType的成員,所以pair_.data 應該是map::value_type類型,進一步就是pair<const int,char*>類型.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved