void push(const t&);
t pop(); // if empty, returns default-
// constructed t
private:
t* v_; // pointer to a memory area big
// enough for 'vsize_' t objects
unsigned vsize_; // the size of the 'v_' area
unsigned vused_; // the number of t's actually
// used in the 'v_' area
};
现在开始讨论实现。首先我们对于t有一个要求:就是t的析构函数必须不能抛出异常。如果析构函数可以抛出异常,要安全的实现许多操作就会是非常的困难甚至是不可能的。
//----- default ctor ----------------------------------------------
template<class t>
stack<t>::stack()
: v_(new t[10]), // 缺省的内存分配
vsize_(10),
vused_(0) // 还没有使用任何内存
{
// 如果程序执行到此,构造函数就成功了
}
//----- copy ctor -------------------------------------------------
template<class t>
stack<t>::stack( const stack<t>& other )
: v_(0), // nothing allocated or used yet
vsize_(other.vsize_),
vused_(other.vused_)
{
v_ = newcopy( other.v_, other.vsize_, other.vsize_ );
// 如果程序执行到此, 拷贝构造函数就成功了
}
//----- copy assignment -------------------------------------------
template<class t>
stack<t>& stack<t>::operator=( const stack<t>& other )
{
if( this != &other )
{
t* v_new = newcopy( other.v_, other.vsize_, other.vsize_ );
//如果程序执行到此, 内存分配和拷贝就成功了
delete[] v_;
// 注意这条语句不能抛出异常,因为t的析构函数不会抛出异常
// 而delete操作符声明为throw()
v_ = v_new;
vsize_ = other.vsize_;
vused_ = other.vused_;
}
return *this; // 安全,不涉及拷贝
}
//----- dtor ------------------------------------------------------
template<class t>
stack<t>::~stack()
{
delete[] v_; // 此处同样不会抛出异常
}
//----- count -----------------------------------------------------
template<class t>
unsigned stack<t>::count()
{
return vused_; // 这是一个原生类型,不会导致异常
}
//----- push ------------------------------------------------------
template<class t>
void stack<t>::push( const t& t )
{
if( vused_ == vsize_ ) // grow if necessary
{
unsigned vsize_new = (vsize_+1)*2; // grow factor
t* v_new = newcopy( v_, vsize_, vsize_new );
file://如果程序执行到此, 内存分配和拷贝就成功了
delete[] v_; // 此处同样不会抛出异常
v_ = v_new;
vsize_ = vsize_new;
}
v_[vused_] = t; // 如果拷贝操作抛出异常,
++vused_; // 因为vused_并没有增长,所以状态没有改变