999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

如何理解C++模板

2014-02-25 02:03:46蘇子偉
軟件工程 2014年2期
關鍵詞:策略

蘇子偉

首先談一下什么是模板。模板就是為解決某一類問題,從而抽象了這類問題的具體共性,為這類問題提供一種通用的解決方法。工作中有很多這樣的例子,比如我們熟知的Microsoft Office中的模板,它給我們的工作帶來了很多便利,改變了每件事都得從頭編碼的做事方法,使得代碼重用變得如此簡單。

C++模板的基礎討論

C++模板的思想也是基于此,它抽象了具體的型別,實現了共性邏輯,為一類問題提供了統一的泛型接口。模板機制使得編程者在定義類和函數時能以類型作為參數,并且模板只依賴于實際使用時的傳入參數,不關心能被用作參數的那些不同類型之間的任何聯系。剛剛接觸C++模板時,可能會感覺它不就是C的#define宏嗎,只是在這里換了一種說法,無非是“新瓶裝舊酒”啊。但是如果你對它感興趣,再深入地理解一下,相信它會帶給你很大的驚喜的。當前,C++模板已經變成了通用編程的基礎,是標準模板庫(STL)的基石。它使得用戶接口更簡單,表達更清晰。

C++是一門靜態的語言,它是強類型檢查的,所以代碼不可能在運行時再編譯生成。而C++模板的技術核心也在于編譯期的代碼解釋和執行期的零成本。雖然這點同#define宏比較類似,但是它實現更簡單,更不容易產生錯誤,使得代碼看起來更具美感,并且它提供函數返回值,可以進行代碼調試,可以進行編譯期的變量類型檢查等等,這些都不是#define宏能比擬的。下面讓我們先看一下C++中如何定義一個模板。

怎么去定義一個模板

C++中有兩種模板,一種是類模板,一種是函數模板,函數模板也可以在類模板中使用。因為模板是編譯期生成代碼的,所以一般我們都把模板代碼放到一個頭文件中聲明定義。首先,我們看一下類模板。

template class ClassName

{

enum { ssize = 50 };

T m_Stack[ssize];

intm_Top_postion;

public:

ClassName () :m_Top_postion(0) { }

voidpush_into(const T& i){

m_Stack[m_Top_postion++] = i;

}

T pop_up() {

returnm_Stack[--m_Top_postion];

}

int size(){

returnm_Top_postion;

}

};

template這個關鍵字告知編譯器,隨后的類定義ClassName將需要一個或更多的類型。這里的T是需要替換的類型參數,你可以指定T為任何你所需要的有意義的類型,比如整型、結構體類型,或者是一個模板類型等。(關于類模板中的常量以及詳細的模板的語法,請參照C++語言程序設計者BjarneStroustrup的大作《C++程序設計語言》)

其次,是函數模板。它用于創建基于泛型為參數的函數。

templateintGetsize(std::vector&param);

這里的template和class的意義同類模板的一樣。但是在函數模板中模板參數必須出現在函數參數中。

模板的實例化

C++模板提供了對源代碼重用的方法,而不像是繼承跟組合提供的對目標代碼的重用方式。這使得處理問題的耦合更小,更簡單,接口更加豐富,代碼量更少。編譯器會根據具體的參數,生成具體問題的解法的特定代碼,這就是模板的實例化。下面讓我們通過一個例子來認識一下模板代碼是怎么生成具體的特定代碼的。

template class ClassName {

T m_data[size];

intm_pos;

public:

ClassName () :m_pos(0) { }

voidput_into(const T& t)

{

m_data[m_pos++] = t;

}

};

下面我們定義一個變量ClassName v;,在這里T的類型變為int,整形參數size沒有改變而是使用了模板中的默認值60。這樣編譯器產生的類代碼如下。

classClassName {

intm_data[60];

intm_pos;

public:

ClassName () :m_pos(0) { }

voidput_into(const T& t)

{

m_data[m_pos++] = t;

}

};

這就是模板參數的實例化過程,根據不同的參數生成了特定的類。函數模板的原理同類模板相同,這里就不在贅述了。

模板的特化

一個模板描述了某個范圍內的一族函數或類。當給定模板參數時,這些模板參數決定了這一族函數或類中的獨一無二的特例,這樣的過程結果被稱為特化。當然模板實例化也是特化的過程。特化分為全特化和半特化,但是函數模板不能半特化,必須一次性的全特化。下面我們分別看看這兩中情況。

首先看看全特化,全特化使用了template<>來標識。

templateconst T& compare(const T& a, const T& b) {

return (a > b) ? a : b;

}

// An explicit specialization of the max template

template<>

const char* const& compare(const char* const& a, const char* const& b) {

return (strlen(a) >strlen(b)) ? a : b;

}

這樣我們使用模板時,例如compare<>(s1,s2)就是使用全特化后的模板生成的最終代碼。compare(4,5)就是使用未全特化的模板生成的最終代碼。

再看一個例子:

template class CAssert;

template<> class CAssert{};

在這個例子中實現的部分跟省略的一樣多,但是它可以工作得很好。它的全特化只是實現了bool型別為true的情況,這樣我們就能使用它在代碼中進行靜態斷言。

再來看一下半特化,半特化又叫偏特化。這種特化方式只是針對于類模板。故名思議,半特化只是部分地特化了模板,約束了符合用戶期望的行為的模板參數,其他參數仍然維持其泛型的性質。編譯器在生成模板代碼時會查找出最匹配的定義,來進行實例化。模板的半特化有很多巧妙的應用,它很好地處理了一些分支問題。下面就以loki庫中的一個例子來看看這種迷人的用法。

比如你需要向一個容器里面插入變量,有時是T,有時是T*。Loki庫的實現如下。

template

struct Select

{

Typedef T result;

};

template

struct Select

{

TypedefU result;

};

Select::result即為需要的型別,只需要根據boolval的值決定。

模板的遞歸模式

這種模板的遞歸方式能使得每個派生類都派生于一個唯一的基類,這個基類使用了它本身作為模板參數。從理論上來說這會產生無休止的遞歸循環,使得編譯器無法推斷出派生類及其基類的具體的型別大小等,但是只要基類中的數據成員不含有與模板型別相關的依賴,模板是可以被實例化出來的。當程序設計者需要派生類具有某些性質,但是這些性質的實現通過繼承又不能很好的處理時,此時可以考慮模板的遞歸模式。下面我們看一下具體的例子。

template class Counted {

staticsize_t count;

public:

Counted() { ++count; }

Counted(const Counted&) { ++count; }

~Counted() { --count; }

staticsize_tgetCount() { return count; }

};

templatesize_t Counted::count = 0;

// children class definitions

classClass1 : public Counted {};

classClass2 : public Counted {};

這樣我們的子類都繼承了唯一的基類,并且基類的型別參數就是其自身。

模板的特征和策略

特征(traits)提供了類或類模板的類型接口,而策略(policy)提供了類或類模板的函數接口。特征和策略被大量地應用到了STL標準模板庫,通過對策略的組合應用,可以使得同一個模板類產生出無與倫比的構建能力,從而涵蓋更多的信息,接口更通用。

下面看一個具體的例子。

#include

#include

class cat {

public:

friendstd::ostream& operator<<(std::ostream&os, const cat&) {

returnos<< "cat!";

}

};

class dog {

public:

friendstd::ostream& operator<<(std::ostream&os, const dog&) {

returnos<< "dog!";

}

};

class Johnson {

public:

friendstd::ostream& operator<<(std::ostream&os, const Johnson&) {

returnos<< "Johnson";

}

};

class Tom {

public:

friendstd::ostream& operator<<(std::ostream&os, const Tom&) {

returnos<< "Tom";

}

};

template class PersonTraits;

template<> class PersonTraits {

public:

typedef cat Favorite_thing;

};

template<> class PersonTraits {

public:

typedef dog Favorite_thing;

};

class dance {

public:

std::stringtodo() { return std::string(" loves to dance."); }

};

class sing {

public:

std::stringtodo() { return std::string(" loves to sing."); }

};

template>

class family {

person who;

typedeftypename traits::Favorite_thingFavorite_thing;

Favorite_thingfav;

actlike_to_do;

public:

family(const person& p) : who(p) {}

voidfavorite_thing() {

std::cout<< who <<" loves " <

}

};

int main()

{

Johnson John;

family fam1(John);

fam1.favorite_thing();

Tom tom;

family fam2(tom);

fam2.favorite_thing();

}

這里面特征就是PersonTraits類里面的Favorite_thing,而策略就是todo()函數。這里我們能夠看到,當把策略組合使用時,就是它們最有用的時候了。程序接口的使用者可以借由組合不同的策略來實現自己需要的高階行為。建立策略類最重要的部分就是如何正確地分解策略。一般來說建立好的策略類,必須遵守的前提就是這些策略類必須是正交的。這樣這些策略類彼此之間是不會產生耦合的。在我們設計類的時候,我們也應該考慮,某個機能如果有一個以上的解決方法,就應該考慮把該機能移出來,做成一個策略。這樣我們就不會把大量的精力花在維護龐大的代碼上了。

由于篇幅有限,本文只是討論了C++模板的部分知識,還有很多有趣的應用等待我們去發掘,C++模板的開發與應用已經進入了一個全新之境。

猜你喜歡
策略
基于“選—練—評”一體化的二輪復習策略
幾何創新題的處理策略
求初相φ的常見策略
例談未知角三角函數值的求解策略
我說你做講策略
“我說你做”講策略
數據分析中的避錯策略
高中數學復習的具體策略
數學大世界(2018年1期)2018-04-12 05:39:14
“唱反調”的策略
幸福(2017年18期)2018-01-03 06:34:53
價格調整 講策略求互動
中國衛生(2016年8期)2016-11-12 13:26:50
主站蜘蛛池模板: 手机精品福利在线观看| 亚洲中字无码AV电影在线观看| 国产精品私拍在线爆乳| 天天躁日日躁狠狠躁中文字幕| 亚洲一区精品视频在线| a毛片在线| 一区二区理伦视频| 四虎精品国产AV二区| 国产一区二区人大臿蕉香蕉| 亚洲男人天堂久久| 日韩专区第一页| av无码一区二区三区在线| 免费jjzz在在线播放国产| 九色综合伊人久久富二代| 日韩精品一区二区三区免费在线观看| 一级毛片免费播放视频| 国产污视频在线观看| 色噜噜久久| 草草影院国产第一页| 日韩在线影院| 8090午夜无码专区| 欧美精品成人| 国产欧美日韩综合在线第一| 国产精品亚洲精品爽爽| 欧美区在线播放| 亚洲欧美人成电影在线观看| 欧美日韩一区二区在线免费观看| 亚洲人成色在线观看| 欧美成人手机在线观看网址| 99精品影院| 成人毛片在线播放| 国产鲁鲁视频在线观看| 中文成人在线| 国产91精品最新在线播放| 亚洲天堂网在线观看视频| a亚洲视频| 日韩精品免费在线视频| 亚洲一本大道在线| 国产欧美在线观看精品一区污| 亚洲h视频在线| 女同国产精品一区二区| 波多野结衣久久高清免费| 在线a视频免费观看| 成年人免费国产视频| 国产人前露出系列视频| 激情五月婷婷综合网| 亚洲精品动漫| 亚洲无码37.| 精品五夜婷香蕉国产线看观看| 亚洲婷婷六月| 欧美性久久久久| 久久久久亚洲精品成人网| 国产成人综合网| 国产精品网址在线观看你懂的| 91精品啪在线观看国产| 呦视频在线一区二区三区| 亚洲综合中文字幕国产精品欧美| 在线a网站| 国产凹凸视频在线观看| 精品色综合| 乱人伦视频中文字幕在线| 人妻无码一区二区视频| 91色在线视频| 国产精品第三页在线看| 亚洲欧美日本国产专区一区| 亚洲区一区| 国产男女XX00免费观看| 国产永久无码观看在线| 国产成人8x视频一区二区| 在线亚洲天堂| 污污网站在线观看| 亚洲有无码中文网| 秋霞一区二区三区| 国产极品粉嫩小泬免费看| 青青青草国产| 中文字幕色在线| 日韩黄色精品| 亚洲成人免费看| 国产麻豆精品在线观看| 亚洲无线国产观看| 国产欧美在线观看一区| 久久精品国产亚洲AV忘忧草18|