以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...