C++类模板

在上篇文章(C++函数模板)中,主要介绍了C++中函数模板,与函数相似,类也可以被一种或多种类型参数化。容器类就是一个具有这种特性的典型的例子,

本文地址:http://www.cnblogs.com/archimedes/p/cpp-class-template.html,转载请注明源地址。

以下通过设计一个类模板Stack的实现来说明:

类模板Stack的实现

#include<iostream>
#include<vector>
#include<stdexcept>
#include<string>
#include<cstdlib>
using namespace std;

template<typename T>
class Stack
{
private:
    vector<T> elems;  //存储元素的容器
public:
    void push(T const&);  //压入元素
    void pop();           //弹出元素
    T top() const;        //返回栈顶元素
    bool empty() const {  //返回栈是否为空
        return elems.empty();
    }
};

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 out_of_range("Stack<>::pop(): empty stack");
    }
    elems.pop_back();
}

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

可以发现,类模板Stack<>是通过C++标准库vector<>来实现的,我们可以不需要亲自设计内存管理、拷贝构造函数和赋值运算

类模板Stack的使用

为了使用类模板对象,必须显式地指定模板实参,下面的例子展示了如何使用类模板Stack<>:

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(exception const& ex) {
        cerr<<"Exception: "<<ex.what()<<endl;
        //return EXIT_FAILURE;
    }
    cin.get();  
    return 0;
}

 通过声明类型Stack<int>,在类模板内部就可以用int实例化T。因此,intStack是一个创建自Stack<int>的对象,它的元素存储于vector,且类型为int,类似,如果声明和使用Stack<string>将会创建相应的对象。
对于类模板,成员函数只有在被使用的时候才被实例化。

显然,这样可以节省时间和空间,另一个好处是:对于那些“未能提供所有成员函数中所有操作的”类型,你可以使用该类型来实例化类模板,只要对那些“未能提供某些操作的”成员函数,模板内部不使用就可以。

你可以像使用其他任何类型一样地使用实例化后的类模板类型(例如Stack<int>),只要它支持所调用的操作就可以:

void foo(Stack<int> const& s)
{
    Stack<int> istack[10];
    ...
}

借助于typedef,可以方便的使用类模板:

typedef Stack<int> IntStack;
void foo(IntStack const& s)
{
    IntStack<int> istack[10];
    ...
}

类模板的特化
可以使用模板实参来特化类模板,和函数模板的重载类似,通过特化类模板,你可以优化基于某种特定类型的实现,或者克服某种特定类型在实例化类模板时所出现的不足。

为了特化一个类,你必须在起始处声明一个template<>,接下来声明用来特化类模板的类型:

template<>
class Stack<string> {
private:
    deque<string> elems;
public:
    void push(string const&);
    void pop();
    string top() const;
    bool empty() const {
        return elems.empty();
    }
};

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

void Stack<string>::pop()
{
    if(elems.empty()) {
        out_of_range("Stack<string>::pop(): empty stack");
    }
    elems.pop_back();
}

string Stack<string>::top()
{
    if(elems.empty()) {
        out_of_range("Stack<string>::top(): empty stack");
    }
    return elems.back();
}

 

posted @ 2014-05-01 16:47  wuyudong  阅读(559)  评论(0编辑  收藏  举报
Top_arrow