C++學習:模闆程式設計
- 函數模闆
- 類模闆
簡介:
衆所周知,C++這門語言是集面向過程,面向對象,以及泛型程式設計于一體的,之前講了面向過程,面向對象,在這裡,簡單講講泛型程式設計.
泛型:也就是無類型,也就是可以容納支援的所有類型.類似java中的ArrayList集合類一樣,在建立的時候去聲明類型,就可以對該類型的對象進行集中的管理操作.泛型程式設計的出現是為了是解決過多備援的代碼而生,想想如果做一個算法的函數,要支援所有類型的,在沒有泛型之前可能要将所有類型都需要重新寫一遍,那麼如果通過泛型程式設計的話,這個時候就可以大大的降低我們的代碼量.
泛型程式設計是獨立于特定類型的方式的編寫代碼
而模闆用于表達邏輯結構相同,但是具體元素類型不同的資料對象的通用行為
這也就是泛型程式設計的好處,在底層代碼中,泛型的應用是十分廣泛的
模闆是泛型程式設計的基礎;
通過模闆可以快速的建立具有類型安全的類庫集合和函數集合,使用模闆可以操作不同的資料類型,進而避免需要為每一個資料類型産生一個特定的類或者函數
提示:
部落客:章飛_906285288
部落格位址;http://blog.csdn.net/qq_29924041
函數模闆
在之前的文章中,應該有過關于泛型的簡單介紹,在這裡做個統籌彙總,在C++中叫函數模闆,在java中也就直接叫泛型程式設計.
所謂函數模闆:實際上是建立一個通用函數,它所用到的資料的類型(包括傳回值類型、形參類型、局部變量類型)可以不具體指定,而是用一個虛拟的類型來代替(實際上是用一個辨別符來占位),等發生函數調用時再根據傳入的實參來逆推出真正的類型。這個通用函數就稱為函數模闆(Function Template)。
函數模闆的定義類型:
注意:
傳回值類型,形式參數類型,局部變量類型都可以用虛拟類型來代替
定義函數模闆的一般形式為:
template < typename T>
傳回值類型 函數名 (參數表) {
}
或者:
template < class T>
傳回值類型 函數名 (參數表) {
}
如一下函數所示:
#include<iostream>
using namespace::std;
namespace zzf{
//定義加減乘除的泛型函數模闆,這個時候就不需要判斷類型了,對于對象的話,如果這個對象對這些運算符進行重載過的話,
//同樣是支援這些運算的
//template <typename T>
template <class T>
T add(T a,T b){
return a + b;
}
template <typename T>
T del(T a,T b){
return a - b;
}
template <class T>
T mul(T a,T b){
return a * b;
}
template <class T>
T div(T a,T b){
return a / b;
}
}
using namespace::zzf;
int main(int argc,char* argv[]){
float ret_1 = add(,);
int ret_2 = add(,);
cout<<"ret_1:" << ret_1<<endl;
cout<<"ret_2:" << ret_2<<endl;
return ;
}
在上述的代碼中,采用的就是無類型的泛型函數模闆形式.
類模闆
類模闆使使用者可以為類定義一種模式,使得類中的某些資料成員、某些成員函數的參數、某些成員函數的傳回值能取任意類型,它跟函數模闆類似
類模闆是對一批成員資料類型不同的類的抽象,程式員隻要為這一批類所組成的整個類家族建立一個類模闆,給出一套程式代碼,就可以用來生成多種具體的類
類模闆就是将要處理的對象的類型參數化,是程式能夠處理不同的對象(資料類型)
類模闆的定義
templete <模闆參數表> //參數表可以是多個
class 類名{
//類成員聲明
};
//在類模闆以外定義其成員
templete <模闆參數表>
類型名 類名<模闆參數表> ::函數名(參數表){
}
對上面的函數進行簡單封裝
/*
* ===========================================================================
*
* Filename: caculatorTemplate.h
* Description:
* Version:
* Created: 年月日 時分秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#ifndef __CACULATORTEMPLATE_H__
#define __CACULATORTEMPLATE_H__
template <class T>
class Caculator{
public:
Caculator(){
}
T add(T a,T b){
return a + b;
}
T del(T a,T b){
return a - b;
}
T mul(T a,T b){
return a * b;
}
T div(T a,T b){
return a / b;
}
~Caculator(){
}
private:
};
#endif
測試代碼
/*
* ===========================================================================
*
* Filename: caculatorTemplateTest.cpp
* Description:
* Version: 1.0
* Created: 2017年06月25日 22時31分22秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#include<iostream>
#include"caculatorTemplate.h"
using namespace::std;
int main(int argc,char* argv[]){
//建立類的執行個體,注意,這個是需要指定類型T的,生成類的模闆
Caculator<int> cacultor;
cout<<cacultor.add(,)<<endl;
return ;
}
注意
1:在建立類的模闆時候,是需要去指定具體的類型的
2:類模闆和模闆類的差別:
類模闆是模闆的定義,不是一個實實在在的類,定義中使用的參數是通用類型參數
模闆類是實實在在的類,是類模闆的執行個體化.類中的參數被實際類型所代替
類模闆是模闆,模闆類是類,模闆是使用.類是定義
案例代碼:打造屬于自己的堆棧管理的模闆類
/*
* ===========================================================================
*
* Filename: stack.h
* Description:
* Version: 1.0
* Created: 2017年06月26日 21時48分06秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#ifndef __STACK_H__
#define __STACK_H__
namespace zzf{
#include<iostream>
using namespace::std;
template <class T>
class Stack{
public:
Stack():top_pointer(){
array[top_pointer] = ;
}
void push(const T& t);
T pop();
T getIndexType(int index);
private:
//C++中一般使用的是枚舉類型來定義常量
enum {ssize = };
T array[ssize];
int top_pointer;
};
/* *
*模闆類必須将定義在頭檔案中
* */
template <class T>
void Stack<T>::push(const T &t){
if(top_pointer < ){
cout << "error top_pointer"<<endl;
}else{
if(top_pointer < ssize){
array[top_pointer] = t;
top_pointer++;
}
}
}
template <class T>
T Stack<T>::pop(){
if(top_pointer < ){
return array[];
}else{
return array[--top_pointer];
}
}
template<class T>
T Stack<T>::getIndexType(int index){
if(index < ) {
cout<<"error index"<<endl;
return array[];
} else {
if(index > top_pointer){
cout<<"error index"<<endl;
return array[];
}else{
return array[index];
}
}
}
}
#endif
/*
* ===========================================================================
*
* Filename: stackTest.cpp
* Description:
* Version: 1.0
* Created: 2017年06月26日 21時59分50秒
* Revision: none
* Compiler: gcc
* Author: (),
* Company:
*
* ===========================================================================
*/
#include<iostream>
#include"stack.h"
using namespace::std;
using namespace::zzf;
int main(int argc,char* argv[]){
Stack<int> stack;
stack.push();
stack.push();
stack.push();
stack.push();
stack.push();
stack.push();
stack.push();
cout<<stack.pop()<<endl;
cout<<stack.getIndexType()<<endl;
return ;
}
注意:
在模闆類中,函數的聲明和定義都需要在頭檔案中進行,否則會出現未定義的引用的錯誤