自定义可以存放任意类型(含智能指针)的顺序栈

来源:互联网 发布:大数据时代读后感5000 编辑:程序博客网 时间:2024/05/17 10:53

今天用模板实现了一个顺序栈。

/*顺序栈*/#ifndef _SEQ_STACK_H_#define _SEQ_STACK_H_#include <iostream>using namespace std;template<class T>class SeqStack{public:SeqStack(unsigned int maxSize = 10);//栈最大值~SeqStack();//析构函数bool isEmpty() const;//是否为空bool isFull() const;//是否满了int size() const;//目前占大小T top()const;//返回栈顶元素,不删除bool push(const T& t);//入栈void pop();//出栈,不返回元素friend ostream& operator<<<>(ostream& out, const SeqStack<T>& s);//输出栈的友员函数private:int nowTop;//目前栈顶int maxTop;//栈的最大值T* stack;//存储元素的动态数组};template<class T>SeqStack<T>::SeqStack(unsigned int maxSize){stack = new T[maxSize];//如果new失败,抛出异常,malloc则是返回NULLmaxTop = maxSize - 1;nowTop = -1;}template<class T>SeqStack<T>::~SeqStack(){delete[] stack;//删除指针}template<class T>bool SeqStack<T>::isEmpty() const{if (nowTop == -1)return true;else return false;}template<class T>bool SeqStack<T>::isFull() const{if (nowTop == maxTop)return true;else return false;}template<class T>int SeqStack<T>::size()const{return nowTop + 1;}template<class T>T SeqStack<T>::top()const{if (!isEmpty())return stack[nowTop];}template<class T>bool SeqStack<T>::push(const T& t)//用引用,避免了一次不必要的拷贝操作{if (isFull())return false;stack[++nowTop] = t;//还是要复制一次return true;}template<class T>void SeqStack<T>::pop(){if (!isEmpty()){T t;stack[nowTop] = t;//重置原来的元素,这样也许可以将智能指针引用减一。nowTop--;}}template<class T>ostream& operator<<(ostream& out, const SeqStack<T>& s)//{for (int i = s.nowTop; i > -1; i--)out << s.stack[i] << endl;return out;}#endif

为了兼容智能指针,我希望在出栈时,智能指针能够自动释放。我的做法是出栈时,构建一个空的智能指针,存放在原来的位置,那么原来的智能指针就会自动销毁。这段代码是我自己想的办法,不知道还有没有更好的办法。毕竟新建一个对象会有一定开销。

template<class T>void SeqStack<T>::pop(){if (!isEmpty()){T t;stack[nowTop] = t;//重置原来的元素,这样也许可以将智能指针引用减一。nowTop--;}}
我也考虑过将原来的置NULL,但是这样的话,如果栈的元素类型不是指针或者智能指针,而是其他类型就会报错。

stack[nowTop] = NULL;
下面是测试代码:

#include <iostream>#include "SeqStack.h"#include <memory>using namespace std;class A{public:A(){ cout << "A construct!" << endl; }~A(){ cout << "A destruct!" << endl; }};void test(){SeqStack<shared_ptr<A>> mStack;mStack.push(make_shared<A>());mStack.push(make_shared<A>());mStack.pop();mStack.pop();mStack.push(make_shared<A>());cout << "test" << endl;}void main(){test();system("pause");}
当把这两句注释后的输出:

template<class T>void SeqStack<T>::pop(){if (!isEmpty()){//T t;//stack[nowTop] = t;//重置原来的元素,这样也许可以将智能指针引用减一。nowTop--;}}
输出:可以看出当第三个智能指针入栈后,原来位置的智能指针才被释放了。函数执行完后,有两个析构,一个是栈中正常的元素,一个是之前没有被正常释放的元素。也就说,如果没有别的写入操作,智能指针的对象会一直存在栈中。

A construct!
A construct!
A construct!
A destruct!
test
A destruct!
A destruct!
请按任意键继续. . .


没有注释时,正常输出:执行pop函数后,智能指针马上被析构。

A construct!
A construct!
A destruct!
A destruct!
A construct!
test
A destruct!
请按任意键继续. . .





0 0
原创粉丝点击