C++类模板

1. 定义类模板

        程序清单类模板-1列出了类模板和成员函数模板,明确这些模板不是类和成员函数定义很重要,因为它们是C++编译指令,说明了如何生成类和成员函数定义。

        不能将模板成员函数放在独立的实现文件中,由于模板不是函数,它们不能单独编译,模板必须与特定的模板实例化请求一起使用。因此,最简单的方式是将所有模板信息放在一个头文件中,并再要使用这些模板的文件中包含该头文件。

//程序清单  类模板-1
//stacktp.h
#ifndef STACKTP_H_
#define STACKTP_H_

template<class Type>
class Stack
{
private:
    enum {MAX = 10};           //Stack类拥有的常量
    Type items[MAX];
    int top;

public:
    Stack();
    bool isempty();
    bool isfull();
    bool push(const Type& item);    //add item to stack
    bool pop(Type& item);           //pop top into item
};

template<class Type>
Stack<Type>::Stack()
{
    top = 0;
}

template<class Type>
bool Stack<Type>::isempty()
{
    return top == 0;
}

template<class Type>
bool Stack<Type>::isfull()
{
    return top == MAX;
}

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

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

#endif

注意模板成员函数定义与类模板声明一起放在模板的头文件中。

2. 使用模板类

        仅在程序中包含模板并不能生成模板类,必须请求实例化,必须显式地提供所需的类型。

Stack<int> kernels;
Stack<std::string> colonels;

3. 深入探讨模板类

        正确使用指针栈的方法之一是,让调用程序提供一个指针数组,其中每个指针都指向不同的字符串。注意,栈的任务是管理指针,不是创建指针。程序清单类模板-2重新定义了Stack<Type>类,使Stack构造函数能够接受一个可选大小的参数。这涉及到在内部使用动态数组,因此Stack类需要包含一个析构函数、一个复制构造函数和一个赋值运算符。

//程序清单 类模板-2
//stcktp1.h

#ifndef STCKTP1_H_
#define STCKTP1_H_

template<class Type>
class Stack
{
private:
    enum {SIZE = 10};  //默认大小
    int stacksize;
    Type* items;
    int top;

public:
    explicit Stack(int ss = SIZE);
    Stack(const Stack& st);
    ~Stack() { delete[] items; }
    bool isempty() { return top == 0; }
    bool isfull() { return top == stacksize; }
    bool push(const Type& item);
    bool pop(Type& item);
    Stack& operator=(const Stack& st);
};

template<class Type>
Stack<Type>::Stack(int ss): stacksize(ss), top(0)
{
    item = new Type[stacksize];
}

template<class Type>
Stack<Type>::Stack(const Stack<Type>& st)
{
    stacksize = st.stacksize;
    top = st.top;
    items = new Type[stacksize];
    for(int i = 0; i < top; i++)
    {
        items[i] = st.items[i];
    }
}

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

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

template<class Type>
Stack<Type>& Stack<Type>::operator=(const Stack<Type>& st)
{
    if(this == &st)
        return *this;
    delete[] items;
    stacksize = st.stacksize;
    top = st.top;
    items = new Type[stacksize];
    for(int i = 0; i < top; i++)
    {
        items[i] = st.items[i];
    }
    return *this;
}

#endif

程序清单类模板-3使用了这个Stack模板类。

//程序清单 类模板-3
//stkoptr1.cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include "stcktp1.h"
const int Num = 10;

int main()
{
    std::srand(std::time(0));
    std::cout << "Please enter stack size: ";
    int stacksize;
    std::cin >> stacksize;

    //create an empty stack with stacksize siots
    Stack<const char*> st(stacksize);

    //in basket
    const char* in[Num] = {
        " 1: Hank Gilgamesh", " 2: Kiki Ishtar",
        " 3: Betty Rocker", " 4: Ian Flagranti",
        " 5: Wolfgang Kibble", " 6: Portia Koop",
        " 7: Joy Almondo", " 8: Xaverie Paprika",
        " 9: Juan Moore", " 10: Misha Mache"
    };

    //out basket
    const char* out[Num];           //类型为const char*,因为指针数组被初始化为一组字符串常量

    int processed = 0;
    int nextin = 0;
    while(processed < Num)
    {
        if(st.isempty())
            st.push(in[nextin++]);
        else if(st.isfull())
            st.pop(out[processed++]);
        else if(std::rand() % 2 && nextin < Num)
            st.push(in[nextin++]);
        else
            st.pop(out[processed++]);
    }

    for(int i = 0; i < Num; i++)
    {
        std::cout << out[i] << std::endl;
    }
    std::cout << "Bye\n";

    return 0;
}

4. 数组模板示例和非类型参数

        模板常用作容器类。

        自己设计一个允许指定数组大小的简单数组模板。一种方法是在类中使用动态数组和构造函数参数来提供元素数目,例如程序清单类模板-2;另一种方法是使用模板参数来提供常规数组的大小,C++11新增的模板array就是这样做的,程

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值