模板之类模板

一:类模板的定义

由于类模板包含类型参数,因此又称为参数化的类。如果说类是对象的抽象,对象是类的实例,则类模板是类的抽象,类是类模板的实例。利用类模板可以建立含各种数据类型的类 eg:vector<>、stack<>。

补充:类模板和模板类的区别

类模板(class template)说明的是该类的一个模板,它代表的是整个类家族的参数描述。

模板类(templa class)是从类模板中产生的类,即由模板名称与紧追其后的尖括号内部的所有实参的组合。


类模板的定义实例:

#include <vector>
#include <stdexcept>


template  <typename T>
class  Stack
{


public:
void push (T const& );
void pop();
T top() const;
bool empty() const
{
return elems.empty();
}


protected:


private:
std::vector<T> elems;


};


template <typename T>
void Stack<T>::push (T const& elem)
{
elems.push_back(elem);
}


template <typename T>
void Stack<T>::pop()
{
if (elems.empty())
{
throw std::out_of_range("Stack<>::pop() :empty stack");
}
elems.pop_back();
}


template <typename T>
T Stack<T>::top() const
{
if (elems.empty())
{
throw std::out_of_range("Stack<>::pop() :empty stack");
}
return elems.back();
}

说明:这个类的类型(即类模板的类型)是:Stack<T>,其中T是模板参数,因此在声明中需要声明该类的类型时,必须使用Stack<T>。eg:为了定义类模板的成员函数,你必须指定该成员函数是一个函数模板,而且还需要用这个类模板的完美类型限定符(上例是stack<T>).

二:类模板的使用

#pragma warning (disable :4786)
#include <iostream>
#include <string>
#include <cstdlib>
#include "stack.h"
using namespace std;
int main()
{
try{
Stack<int>   intstack;
Stack<string>  stringstack;


intstack.push(7);
cout<<intstack.top()<<endl;


stringstack.push("hello");
cout<<stringstack.top()<<endl;
stringstack.pop();
stringstack.pop();
}catch (std::exception const& ex) {
std::cerr<<"Exception: "<<ex.what()<<endl;
return EXIT_FAILURE;
}

return 0;


}

三:类模板的特化

在进行类模板的特化时,每个成员函数都必须重新定义为普通函数,原来模板函数中的每个T也相应地被进行特定的类型取代

四:局部特化

类模板可以被局部特化,你可以在特定的环境下指定类模板的特定实现,并且要求某些模板参数仍然必须有用户来定义。

eg:对于这样的类模板:

template <typename T1,typename T2>

class MyClass

{      .........  };

其有下列几种局部特化:

(1)

template <typename T>

class MyClass <T,T>

{      .........  };

(2)

template <typename T>

class MyClass <T,int>

{      .........  };

(3)

template <typename T1,typename T2>

class MyClass <T1*,T2*>

{      .........  };

这就以使用他们

Myclass<int,float>mif    //使用Myclass<T1,T2>

Myclass<float,float>mff  //使用Myclass<T,T>

Myclass<float,int> mfi    //使用Myclass<t,int>

Myclass<int *,float *>mp   //实用Myclass<T1*,T2*>

但是使用时防止产生二义性:eg:MyClass<int,int>m  //MyClass<T,T>和MyClass<T,int>都可以匹配


四:缺省模板实参

#include <vector>
#include <stdexcept>


template  <typename T,typename cont=std::vector<T> >
class  Stack
{


public:
void push (T const& );
void pop();
T top() const;
bool empty() const
{
return elems.empty();
}


protected:


private:
cont  elems;


};


template  <typename T,typename cont=std::vector<T> >
void Stack<T>::push (T const& elem)
{
elems.push_back(elem);
}


template  <typename T,typename cont=std::vector<T> >
void Stack<T>::pop()
{
if (elems.empty())
{
throw std::out_of_range("Stack<>::pop() :empty stack");
}
elems.pop_back();
}


template  <typename T,typename cont=std::vector<T> >
T Stack<T>::top() const
{
if (elems.empty())
{
throw std::out_of_range("Stack<>::pop() :empty stack");
}
return elems.back();
}



使用时可以是:

 Stack<int>  intStack;

Stack<double,std::queue<double> > doublesStack;      //声明了一个”元素类型为double,并且使用std:queue<>在内部管理元素“的栈;


小结:

类模板是具有如下性质的类:

在类的实现中,可以有一个或多个类型还没有被指定。

为了使用类模板,你可以传入某个具体类型作为模板参数,然后编译器将会基于该类型来实例化类模板。

对于类模板而言,只有那些被调用的成员函数才会被实例化

可以用某种特定类型特定化类模板

可以用某种特定类型局部特化类模板

可以为类模板的参数定义缺省值,这些值还可以引用之前的模板参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值