栈:
#include <iostream>
#include <assert.h>
using namespace std;
template <class T>
class Stack
{
public:
//构造函数:
Stack(size_t capacity = 4)
:_a(nullptr)
,_top(0)
{
if (capacity > 0)
{
_a = new T[capacity];
_capacity = capacity;
_top = 0;
}
}
//析构函数:
~Stack()
{
delete[] _a;
_a = nullptr;
_top = _capacity = 0;
}
//入栈:
void Push(const T& x)
{
if (_top == _capacity)
{
size_t newCapacity = _capacity == 0 ? 4 : _capacity * 2;
T* newA = new T[newCapacity];
if (_a)
{
memcpy(newA, _a, sizeof(T) * _top);//把a空间对应的数据拷贝到newA里
delete[] _a;
}
_a = newA;
_capacity = newCapacity;
}
_a[_top] = x;
_top++;
}
//出栈:
void Pop()
{
assert(_top > 0);
_top--;
}
//判空:
bool Empty()
{
return _top == 0;
}
//栈顶元素:
//数据存放在堆上,出了栈数据并未销毁,故采用引用返回
T& Top()
{
assert(!Empty());
return _a[_top-1];
}
//栈的有效长度:
size_t Size()
{
assert(!Empty());
return _top;
}
private:
T* _a;
size_t _top;
size_t _capacity;
};
int main()
{
try
{
Stack<int> st1;
Stack<char> st2;
st1.Push(1);
st1.Push(2);
st1.Push(3);
st1.Push(4);
//依次输出栈顶的同时销毁栈顶:
while (!st1.Empty())
{
cout << st1.Top() << " ";
st1.Pop();
}
cout << endl;
}
catch(const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
一些小补充:
1.类模板必须显示类型:
class Stack
{
public:
//构造
//析构
//入栈
//...
private:
T* _a;
size_t _top;
size_t _capacity;
};
int main()
{
//类模板必须显示类型
Stack<T> st1;
return 0;
}
2.修改栈顶元素:
class Stack
{
public:
//构造
//析构
//入栈
//...
private:
T* _a;
size_t _top;
size_t _capacity;
};
int main()
{
//类模板必须显示类型
Stack<T> st1;
//压栈:1,2,3,4
//修改栈顶元素4,为之前的二倍并输出:
cout << (st1.Top() *= 2) << endl;
return 0;
}
原因:因为Top()函数是引用返回,返回值就是它本身。
3.模板不支持分离编译(声明在.h,定义在.cpp)
模板在同一个文件中是可以分离声明和定义的。
但类的定义也和一般的函数不一样:
class Stack
{
public:
//构造
//析构
//入栈
void Push(const T& x);
//...
private:
T* _a;
size_t _top;
size_t _capacity;
};
void Stack<T>::Push(const T& x)
{
if (_top == _capacity)
{
size_t newCapacity = _capacity == 0 ? 4 : _capacity * 2;
T* newA = new T[newCapacity];
if (_a)
{
memcpy(newA, _a, sizeof(T) * _top);//把a空间对应的数据拷贝到newA里
delete[] _a;
}
_a = newA;
_capacity = newCapacity;
}
_a[_top] = x;
_top++;
}
int main()
{
//类模板必须显示类型
Stack<T> st1;
return 0;
}