Exception C++中讨论的异常安全栈,封装内存管理的版本,使用"成员变量"的方式实现
来源:互联网 发布:真伸缩金刚狼爪子淘宝 编辑:程序博客网 时间:2024/05/21 10:01
#include <new>
template<class T1, class T2>
void construct(T1* p,const T2& val)
{
new (p) T1(val);//placement new
}
template <class T>
void destroy(T* p)
{
p->~T();
}
template <class FwdIter>
void destroy(FwdIter first,FwdIter last)
{
while (first != last)
{
destroy(&*first);
++first;
}
}
template <class T>
void swap(T& a,T& b)
{
T temp(a); a=b;b=temp;
}
template<class T>
class StackImpl
{
public:
StackImpl(size_t size):
v_(static_cast<T*>
(size == 0 ? 0 :operator new (sizeof(T)*size))),
vused_(0),
vsize_(size)
{}// new operator
~StackImpl()
{
destroy(v_,v_ + vused_);
operator delete (v_);
}
void Swap(StackImpl& other) throw()
{
swap(v_,other.v_);
swap(vsize_,other.vsize_);
swap(vused_,other.vused_);
}
T* v_;
size_t vsize_;
size_t vused_;
private:
StackImpl(const StackImpl& other);
StackImpl& operator=(const StackImpl& other);
};
template<class T>
class Stack
{
public:
Stack(size_t size=0):impl_(size)
{}
Stack(const Stack& other):impl_(other.impl_.vused_)
{
while(impl_.vused_ < other.impl_.vused_)
{
construct(impl_.v_+impl_.vused_,other.impl_.v_[impl_.vused_]);
++impl_.vused_;
}
}
Stack& operator=(const Stack& other)
{
Stack temp(other);
impl_.Swap(temp.impl_);
return *this;
}
~Stack()
{
}
bool Empty()
{
return 0 == impl_.vused_;
}
size_t Count()const
{
return impl_.vused_;
}
void Push(const T& t)
{
if(impl_.vused_ == impl_.vsize_)
{
Stack temp(2*impl_.vsize_ + 1);
while(temp.Count() < impl_.vused_)
{
temp.Push(impl_.v_[temp.Count()]);
}
temp.Push(t);
impl_.Swap(temp.impl_);
}
else
{
construct(impl_.v_+impl_.vused_,t);
++impl_.vused_;
}
}
void Pop()
{
if (impl_.vused_ == 0)
{
throw "pop from empty stack";
}
else
{
--impl_.vused_;
destroy(impl_.v_+impl_.vused_);
}
}
T& Top()
{
if (impl_.vused_ == 0)
{
throw "empty stack";
}
return impl_.v_[impl_.vused_-1];
}
private:
StackImpl<T> impl_;
};
说明:使用StackImpl封装内存管理,Stack对外提供接口实现。
如果没有特殊的要求,比如基类对象要优先初始化,或者覆盖基类的虚函数,优先使用最后一个组合的版本实现栈。
这两个使用了StackImpl版本的优点是:
对T的要求只有两个:(1)T的析构函数不抛异常;(2)T有copy constructor;
而第一个简单版本对T的要求:除上面二者外,还需要default constructor and Exception-safe 's copy assignment.
明显后续两个版本的实现对T的要求更少,更利于Stack容器的复用。
在C++标准库中的容器和迭代器而言,除了多元素插入不是强异常安全的,还有vector<T>,deque<T>不是的插入和删除不是强异常安全的,其余都是强异常安全的。
对于这两个例外,可以使用temp and swap的方式来实现。
- Exception C++中讨论的异常安全栈,封装内存管理的版本,使用"成员变量"的方式实现
- Exception C++中讨论的异常安全堆栈的,封装内存管理的版本,使用私有继承的方式复用
- 【objective-c】内存管理中成员变量声明参数的一些总结
- 关于java中final方法,类,成员变量的讨论
- 内存使用的管理方式
- 内存管理:类变量、成员变量、实例变量、局部变量、静态变量、全局变量 的解释。
- 类中对集合成员变量的封装
- 讨论计算机系统内存中各类变量的内存大小
- 老掉牙:成员变量与成员方法的讨论
- Bash中变量的讨论
- C#-面向对象的三大特性——封装(封装成员变量、封装成员方法)
- OC阅读笔记十五:"异常安全代码"的内存管理
- JAVA中静态成员变量的使用
- C++_类_不同类型成员变量的初始化方式
- C/C++中结构体与类成员变量在存储上的内存对齐问题
- Objective-c的内存管理方式
- C/C++中变量及函数命名的讨论
- Java中成员变量和成员方法的使用
- ping源码代阅读(二) 基本知识介绍
- chrome的主页
- conky 配置变量表
- VB6.0属性过程详解(Property过程)[第三章:枚举属性和OLE_COLOR类型(设计限定输入的属性,如DragMode属性)]
- HDU 2722 Here We Go(relians) Again
- Exception C++中讨论的异常安全栈,封装内存管理的版本,使用"成员变量"的方式实现
- 卸载oracle
- 人临终最后悔的五件事:
- 基于用户管理的备份与恢复-控制文件的备份与恢复
- git命令备忘录
- 深入学习heritrix---体系结构(Overview of the crawler)
- 离去
- oracle数学函数
- 录Charles F. Kettering名言一组