C C 程式設計 類模板

2021-10-11 01:12:17 字數 4706 閱讀 2875

以stack為例學習類模板的使用

stack.hpp

#pragma once

#include

#include

template

<

typename t>

class

stack

/* 拷貝建構函式

賦值運算子

*///stack(stackconst &);

//stack& operator=(stackconst &);};

template

<

typename t>

void stack

::push

(const t & elem)

template

<

typename t>

void stack

::pop()

elems.

pop_back()

;// 刪除最後乙個元素}}

template

<

typename t>

t stack

::top (

)const

return elems.

back()

;// 返回最後乙個元素的拷貝

}

可以看出,類模板stack<>是通過c++標準庫的類模板vector<>來實現的:因此,我們不需要親自實現記憶體管理、拷貝建構函式和賦值運算子,只需要把精力放在該類模板的介面上

#include

#include

#include

#include

"stack.h"

void

foo(stack<

int>

const

&s)// 和上面效果一樣

typedef stack<

int>intstack ;

// 起乙個別名

void

foo1

(intstack const

&s)int main (

)catch

(std::exception const

& ex)

}

可以使用模板實參來特化類模板。

為了特化乙個類模板,你必須在起始處宣告乙個template<>,接下來宣告用來特化類模板的型別。這個型別被用作模板實參,而且必須在類名的後面直接指定:

template

<

>

class

stack

進行類模板的特化時,每個成員函式都必須重新定義為普通函式,原來模板函式中的每個t也相應的被進行特化的型別取代:

void stack

::push (std::string const

& elem)

下面stack2.hpp是乙個用std::string特化stack<>的完整例子:

#pragma once

#include

"stack.h"

#include

#include

#include

template

<

>

class

stack

};void stack

::push (std::string const

& elem)

void stack

::pop (

) elems.

pop_back()

;// 刪除末端元素

}std::string stack

::top (

)const

return elems.

back()

;}

在上面的例子中,我們使用了deque而不是vector來管理元素,可以看出,特化的實現可以和基本類模板的實現完全不同

使用方法和第乙個一樣,只是在使用stack時會呼叫stack1.hpp而不是stack.hpp。當然stackintstack還是呼叫stack.hpp

類模板特化時:

可以在原來的成員函式的基礎上再擴充套件別的功能

當然,我們也可以使用每種特定型別區域性特化類模板(待補)

類模板可以被區域性特化,你可以在特定的環境下指定類模板的實現,並且要求某些模板引數仍然必須由使用者來定義,比如類模板:

template

<

typename t1,

typename t2>

class

myclass

;

就可以有下面幾種區域性特化:

// 區域性特化1:兩個模板引數具有相同的型別

template

<

typename t>

class

myclass

;// 區域性特化:第二個模板引數的型別時int

template

<

typename t>

class

myclas

int>

;//區域性特化:兩個模板引數都是指標型別

template

<

typename t1,

typename t2>

class

myclass

, t2*

>

下面的例子展示各種宣告會使用哪個模板:

myclass<

int,

float

> mif;

// myclass

myclass<

float

,float

> mff;

// myclass

myclass<

float

,int

> mfi;

// myclass

myclass<

int*

,float

*> mp;

//myclass

如果有多個區域性特化同等程度的匹配某個宣告,那麼就稱該宣告具有二義性:

myclass<

int,

int> m;

// 錯誤:同時匹配myclass和myclass

myclass<

int*

,int

*> m;

// 錯誤:同時匹配myclass和myclass

為了解決第2種二義性,你可以提供乙個指向相同型別指標的特化:

template

<

typename t>

class

myclass

, t*

>

;

對於類模板,我們可以為模板引數定義預設值,這些值就被稱為預設模板實參;比如:在上面我們知道,對於stack<>,我們可以用陣列、佇列等來管理元素。我們可以把用於管理元素的容器定義為第2個引數,並且使用std::vector<>作為它的預設值

#pragma once

#include

#include

#include

#include

template

<

typename t,

typename cont = std::vector

>

class

stack};

template

<

typename t,

typename cont>

void stack

::push (t const

& elem)

template

<

typename t,

typename cont>

void stack

::pop (

) elems.

pop_back()

;// remove last element

}template

<

typename t,

typename cont>

t stack

::top (

)const

return elems.

back()

;// return copy of last element

}

使用

#include

#include

#include

#include

#include

"stack2.h"

int main (

)catch

(std::exception const

& ex)

}

C C 類模板

類模板就是為類宣告一種模板,使得類中的某些資料成員,或某些成員函式的引數,又或者是某些成員函式的返回值可以取任意的資料型別,包括基本資料型別和自定義資料型別。類模板的宣告形式如下 template 模板參數列 類宣告 模板參數列中可以以下兩種模板引數 1.class 識別符號 指明可以接受乙個型別引...

C C 程式設計 模板中的this

對於具有基類的類模板,自身使用名稱x並不一定等同於this x。即使該類x是從基類繼承獲得的,也是如此。例如 在這個例子中,在foo 內部決定要呼叫哪乙個exit 時,並不會考慮基類base中定義的exit 因此,會出錯或者呼叫系統庫中的exit 規則 對於那些在基類中宣告,並且依賴於模板引數的符合...

C 模板程式設計 函式模板 類模板

通常int sum int a,int b 這裡的兩個形參變數a b,就是為了接受實參的值。而模板的意義就在於此,模板就是針對型別的,使型別也可以進行引數化,即由原來的的固定的轉化為可變的。模板的意義 對型別也可以進行引數化了 裡面的內容不進行編譯,型別不知道 1 定義乙個模板形參列表 templa...