如何写模板类?(模板类的简单例子)

本文通过c++ primer plus中的例子来学习写模板类.

1.为什么需要模板类?

为了满足代码重用的需求.
比如stack类,希望不同的类型都能用.
先看看用typedef 定义的stack类.

// stack.h -- class definition for the stack ADT
#ifndef STACK_H_
#define STACK_H_

typedef unsigned long Item;
class Stack
{
private:
    enum {MAX = 10};    // constant specific to class
    Item items[MAX];    // holds stack items
    int top;            // index for top stack item
public:
    Stack();
    bool isempty() const;
    bool isfull() const;
    // push() returns false if stack already is full, true otherwise
    bool push(const Item & item);   // add item to stack
    // pop() returns false if stack already is empty, true otherwise
    bool pop(Item & item);          // pop top into item
};
Stack::Stack()    // create an empty stack
{
    top = 0;
}

bool Stack::isempty() const
{
    return top == 0;
}

bool Stack::isfull() const
{
    return top == MAX;
}

bool Stack::push(const Item & item)   
{
    if (top < MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}

bool Stack::pop(Item & item)
{
    if (top > 0)
    {
        item = items[--top];
        return true;
    }
    else
        return false; 
}
#endif

此时能操作的类型是unsigned long;现在如果希望stack还能够操作string,该怎么办呢?
如果还用typedef定义,就要多一份类似的代码.
这个时候模板类就发挥作用了.

2.改写为模板类

使用模板类改写stack如下

// stacktp.h -- a stack template
#ifndef STACKTP_H_
#define STACKTP_H_
template 
class Stack
{
private:
    enum {MAX = 10};    // constant specific to class
    Type items[MAX];    // holds stack items
    int top;            // index for top stack item
public:
    Stack();
    bool isempty();
    bool isfull();
    bool push(const Type & item); // add item to stack
    bool pop(Type & item);        // pop top into item
};

template 
Stack::Stack()
{
    top = 0;
}

template 
bool Stack::isempty()
{
    return top == 0;
}

template 
bool Stack::isfull()
{
    return top == MAX;
}

template 
bool Stack::push(const Type & item)
{
    if (top < MAX)
    {
        items[top++] = item;
        return true;
    }
    else
        return false;
}

template 
bool Stack::pop(Type & item)
{
    if (top > 0)
    {
        item = items[--top];
        return true;
    }
    else
        return false; 
}

#endif

(1)将typedef替换为template ,关键字template告诉编译器要定义一个模板,尖括号内容相当于函数的参数列表.class相当于变量的类型名,Type相当于变量的值,变量接受类型作为其值.
(2)使用泛型名Type替换标识符Item,Type是一个通用类型说明符,在使用模板是将使用实际类型替代它.
(3)在每个函数前面使用模板声明template 打头.并且在类名后面要
对比stack构造函数,未使用模板类前,

Stack::Stack()    // create an empty stack
{
    top = 0;
}

使用模板类后

template 
Stack::Stack()
{
    top = 0;
}

3.使用

使用的时候给类传递类型名就可以了

Stack kernels;
Stack colonels;

4.模板中的非类型参数使用

经常看到这样的模板定义,

template 

int n代表什么呢?此时该如何使用呢
int n指出n的类型是int,这种类型称为非类型参数或者表达式参数.
template
class ArrayTP
以下的ArrayTP类如果按照
ArrayTP<double,12> eggWeight的方式调用,表示用double替换T,12替换n.

//arraytp.h  -- Array Template
#ifndef ARRAYTP_H_
#define ARRAYTP_H_

#include 
#include 

template 
class ArrayTP
{
private:
    T ar[n];
public:
    ArrayTP() {};
    explicit ArrayTP(const T & v);
    virtual T & operator[](int i);
    virtual T operator[](int i) const;
};

template 
ArrayTP::ArrayTP(const T & v)
{
    for (int i = 0; i < n; i++)
        ar[i] = v;
}

template 
T & ArrayTP::operator[](int i)
{
    if (i < 0 || i >= n)
    {
        std::cerr << "Error in array limits: " << i
            << " is out of range\n";
        std::exit(EXIT_FAILURE);
    }
    return ar[i];
}

template 
T ArrayTP::operator[](int i) const
{
    if (i < 0 || i >= n)
    {
        std::cerr << "Error in array limits: " << i
            << " is out of range\n";
        std::exit(EXIT_FAILURE);
    }
    return ar[i]; 
}

#endif

你可能感兴趣的:(C++编程语言学习)