侯捷老師在《stl 原始碼剖析》說:traits程式設計方法是一把開啟stl源**大門的鑰匙,其重要性也就不必再說了。既然traits程式設計方法如此重要,那麼掌握並領悟其精髓是相當必要了。
trait的意思是什麼?英文意思是attribute,feature等等,中文意思可以解釋為特點, 特性。那麼type trait就是型別的特性。那什麼是型別?型別的特性又有哪些呢?型別也即是使用者自定義的型別或是語言提供的一些基本型別。每個型別都具有相關的特性,這些特性可能包括:是否有相應的構造方法和析構方法、這一型別引申出來相應的指標型別和引用型別(比如iterator_traits中的成員)等等。其實乙個型別所具有的特性是多得數也數不清的,只能從實踐(程式設計)的需要去看這個型別具有什麼樣的特性。如stl中的destroy需根據型別是否具備有關痛癢的析構方法來決定具體操作。是否具備有關痛癢的析構方法就是型別的乙個特性,在程式設計實踐中的特性。自定義的型別可能就具備有關痛癢的析構方法,而語言提供的一些基本型別就沒有。
traits技巧對型別做了什麼?有什麼作用?型別和型別的特性本是耦合在一起,通過traits技巧就可以將兩者解耦。從某種意思上說traits方法也是對型別的特性做了泛化的工作,通過traits提供的型別特性是泛化的型別特性。從演算法使用traits角度看,使用某一泛型型別的演算法不必關注具體的型別特性(關注的是泛化的型別特性,即通過traits提供的型別特性)就可以做出正確的演算法過程操作;從可擴充套件角度看,增加或修改新的型別不影響其它的**,但如果是在type_traits類中增加或修改型別特性對其它**有極大的影響;從效率方法看,使用type_traits的演算法多型性選擇是在編譯時決定的,比起在執行時決定效率更好。
在實際**中所有的具體的型別特性沒有基類,但概念上是存在的。如果我們再把通過引數多型性的演算法也看成有基類情況的假想,就有下圖所示的關係:
從圖中可看出演算法destroy不必關心具體的型別特性traits,client不用關心具體的destroy。destroy概念上存在的基類是通過引數多型實現的,traits概念上存在的基類是通過type_traits程式設計方法實現的。
另外得注意的是stl中的iterator相關type_traits的使用跟這裡所說的有點不同,如果把型別特性從類中剝離出來看待,那就完全相同了。如何剝離,分析**時遇到type_traits相關的含有型別特性的類只看成是型別特性,跟型別特性無關的全都忽略掉。
// my_type_traits.h開始
#ifndef my_type_traits_h
#define my_type_traits_h
struct my_true_type ;
struct my_false_type ;
template
struct my_type_traits ;
template<> struct my_type_traits ;
#endif
// my_type_traits.h結束
// my_destruct.h開始
#ifndef my_destruct_h
#define my_destruct_h
#include
#include "my_type_traits.h"
using std::cout;
using std::endl;
template
inline void myconstruct(t1 *p, const t2& value)
template
inline void mydestroy(t *p)
template
inline void _mydestroy(t *p, my_true_type)
template
inline void _mydestroy(t *p, my_false_type)
#endif
// my_destruct.h結束
// test_type_traits.cpp開始
#include
#include "my_destruct.h"
using std::cout;
using std::endl;
class testclass
testclass(const testclass& test_class)
~testclass()
private:
int *data;
};
int main(void)
}// test_type_traits.cpp結束
繼承本質論
1.引言 關於繼承,你是否駕熟就輕,關於繼承,你是否瞭如指掌。本文不討論繼承的基本概念,我們回歸本質,從編譯器執行的角度來揭示.net繼承中的執行本源,來發現子類物件是如何實現了對父類成員與方法的繼承,以最為簡陋的示例來揭示繼承的實質,闡述繼承機制是如何被執行的,這對於更好的理解繼承,是必要且必然的...
繼承本質論
原創作品,轉貼請註明作者和出處。關於繼承,你是否駕熟就輕,關於繼承,你是否瞭如指掌。本文不討論繼承的基本概念,我們回歸本質,從編譯器執行的角度來揭示.net繼承中的執行本源,來發現子類物件是如何實現了對父類成員與方法的繼承,以最為簡陋的示例來揭示繼承的實質,闡述繼承機制是如何被執行的,這對於更好的理...
指標本質論
指標本質論 1.指標是什麼?和一般變數有什麼區別?指標就是位址,和一般變數沒有本質區別,僅僅是它有自己的規則。int a 100 int p a printf d n a 100 printf p n p 0xbfa47858 a是乙個變數名,型別是int,值是100,a有自己的位址 a p是乙個變...