C++ Template非类型的类模板参数(4.1节)

    对于函数模板和类模板,模板参数并不局限于类型,普通值也可以作为模板参数。在基于类型参数的模板中,定义一些具体细节未加确定的代码,直到代码被调用时这些细节才被真正确定。然而,在这里,我们面对的这些细节是值(value),而不是类型。当要使用基于值的模板时,你必须显式地指定这些值,才能够对模板进行实例化,并获得最终代码。

    较之前的Stack例子的实现,可以使用元素数目固定的数组来实现Stack。这个方法(用固定大小的数组)的优点是:无论是由你来亲自管理内存,还是由标准容器来管理内存都可以避免内存管理开销。然而,决定一个栈(stack)的最佳容量是很困难的。如果你指定的容量太小,那么栈可能会溢出;如果指定的容量太大,那么可能会不必要地浪费内存。一个好的解决方法就是:让栈的用户亲自指定数组的大小,并把它作为所需要的栈元素的最大个数。
例如:

//stack4.h
#ifndef STACK4_H
#define STACK4_H

#include <stdexcept>
#include <iostream>

template<typename T, int MAXSIZE>
class Stack {
private:
    T elems[MAXSIZE];               //包含元素的数组
    int numElems;                   //无素的当前总个数

public:
    Stack();                        //构造函数
    void push(T const &elem);       //压入元素
    void pop();                     //弹出元素
    T top() const;                  //返回栈顶元素
    bool empty() const {            //返回栈是否为空
        return numElems == 0;
    }
    bool full() const {             //返回栈是否已满
        return numElems == MAXSIZE;
    }
};

//构造函数
template <typename T, int MAXSIZE>
Stack <T, MAXSIZE>::Stack()
    :numElems(0)                    //numElems初始化为0
{
    std::cout << "constructor==========Stack===========" << std::endl;
}

template<typename T, int MAXSIZE>
void Stack<T, MAXSIZE>::push(T const &elem)
{
    if(numElems == MAXSIZE) {
        throw std::out_of_range("Stack<>::push(): stack is full");
    }
    elems[numElems] = elem;            //附加元素
    ++numElems;                         //增加元素的个数
}

template<typename T, int MAXSIZE>
void Stack<T, MAXSIZE>::pop()
{
    if(numElems <= 0) {
        throw std::out_of_range("Stack<>::pop(): empty stack");
    }
    --numElems;                         //减少元素的个数
}

template <typename T, int MAXSIZE>
T Stack<T, MAXSIZE>::top() const
{
    if(numElems <= 0) {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
    std::cout << "top()=====numElems=====" << numElems << std::endl;
    return elems[numElems - 1];         //返回最后一个元素
}

#endif // STACK4_H

 为了使用这个类模板,你需要同时指定元素的类型和个数(即栈的最大容量)

//stack4test.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include "stack4.h"


int main()
{
    try {
        Stack<int, 20>          int20Stack; //可以存储20个int元素的栈
        Stack<int, 40>          int40Stack; //可以存储40个int元素的栈
        Stack<std::string, 40>  stringStack;//可存储40个string元素的栈
        //使用可存储20个int元素的栈
        int20Stack.push(89);
        std::cout << int20Stack.top() << std::endl;
        int20Stack.pop();

        //使用可存储40个string的栈
        stringStack.push("hello");
        std::cout << stringStack.top() << std::endl;
        stringStack.pop();
        stringStack.pop();
    } catch (std::exception const &ex) {
        std::cerr << "Exception: " << ex.what() << std::endl;
        return EXIT_FAILURE; //退出程序且有ERROR标记
    }
    return 0;
}

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值