http://hi.baidu.com/qingshanyin/blog/item/9e13132428a439358644f958.html
1、前言
栈是LIFO序列(后进先出),ACE既支持动态栈,也支持静态栈,静态栈的尺寸固定,使用代价较低。ACE提供了两种静态栈:有界栈 ACE_Bounded_Stack和固定栈ACE_Fixed_Stack。动态栈在每次插入时候分配内存,每次弹出时候释放该内存,即无界栈 ACE_Unbounded_Stack类型。
有界栈和固定栈的区别在于:有界栈是在运行时固定下来的,方法是把尺寸作为参数传递给栈的构造器:
ACE_Bounded_Stack<DataElement>bstack(100);
固定栈的尺寸是在编译时确定的,在内部,固定栈使用的是一个数组。
ACE_Fixed_Stack<DataElement*,100> bstack1;
而无界栈ACE_Unbounded_Stack内部实际上使用的是一个链表表示,因此有意思的是,除了常规弹出操作外,也可以用迭代器遍历无界栈。
2、测试全部源代码,含有全部注释
#define ACE_NTRACE 0
#include "ace/Containers_T.h"
class DataElement;
class StackTests
{
public:
//测试有界栈
//有界栈是一种静态栈:大小固定
//有界栈在开始时候必须进行初始堆分配
static int runBoundedStack(void)
{
ACE_TRACE(ACE_TEXT("StackTests:runBoundedStack"));
ACE_DEBUG((LM_DEBUG,ACE_TEXT("Using a bounded stack/n")));
//有界栈声明:栈的元素是元素值,非指针,即其为值容器
//因为是值容器,当本函数退出时,bstack1的析构器被调用时,容器中的元素也将全部被释放(销毁)
ACE_Bounded_Stack<DataElement>bstack1(100);//有界栈初始堆分配,必须进行
{
//所有元素均在栈上创建,因此离开作用域后,数组及数组中的元素将被销毁
DataElement element[100];
for(int i=0;i<100;i++)
{
element[i].setData(i);
//将对象压入栈中
bstack1.push(element[i]);
}
}
//第二个有界栈栈声明:值容器
ACE_Bounded_Stack<DataElement> bstack2(100);
//栈复制:深度复制--元素全部复制过来
bstack2=bstack1;
while(!bstack2.is_empty())
{
DataElement element;
//将元素弹出栈,从栈中移除所有元素
bstack2.pop(element);//弹出的对象是值元素,因此离开作用域时候,元素将被自动销毁
ACE_DEBUG((LM_DEBUG,ACE_TEXT("%d "),element.getData()));
}
ACE_DEBUG((LM_DEBUG,ACE_TEXT("/n")));
return 0;
}
//固定栈测试
//固定栈也是一种静态栈
//固定栈与有界栈的区别是:它是在声明时,用模板参数设定栈大小,而有界栈则在声明时需要进行初始堆分配
int runFixedStack(void)
{
ACE_TRACE(ACE_TEXT("StackTests:runFixedStack"));
ACE_DEBUG((LM_DEBUG,ACE_TEXT("Using a fixed stack/n")));
//固定栈声明,注意第二个参数设定栈大小
//栈中的元素是指针,因此当栈离开作用域前,必须弹出并删除栈中所有元素
//否则会造成内存泄漏
ACE_Fixed_Stack<DataElement*,100> fstack;
for(int i=0;i<100;i++)
{
DataElement* element;
ACE_NEW_RETURN(element,DataElement(i),-1);
fstack.push(element);//指针元素压栈
}
for(int j=0;j<100;j++)
{
DataElement* element;
//指针元素出栈
fstack.pop(element);
ACE_DEBUG((LM_DEBUG,ACE_TEXT("%d "),element->getData()));
//删除元素,否则造成内存泄漏
delete element;
}
ACE_DEBUG((LM_DEBUG,ACE_TEXT("/n")));
//离开作用域,栈将被销毁(元素在出栈后已经销毁:delete element;)
return 0;
}
//无界栈实际上内部使用的是一种链表表示
//因此我们可以用迭代器来遍历栈中的每一个元素
//当然按照使用栈的惯例,我们一般不使用迭代器来遍历这些元素,而是用弹出的方式来使用
int runUnboundedStack(void)
{
ACE_TRACE(ACE_TEXT("StackTests::runUnboundedStack"));
ACE_DEBUG((LM_DEBUG,ACE_TEXT("Using a unbounded stack/n")));
//栈声明:注意栈中元素是指针
ACE_Unbounded_Stack<DataElement*> ustack;
for(int i=0;i<100;i++)
{
DataElement* element;
ACE_NEW_RETURN(element,DataElement(i),-1);
ustack.push(element);
}
//栈使用的常规方法:弹出
while(!ustack.is_empty())
{
DataElement* element;
ustack.pop(element);
ACE_DEBUG((LM_DEBUG,ACE_TEXT("%d "),element->getData()));
delete element;
}
ACE_DEBUG((LM_DEBUG,ACE_TEXT("/n")));
//使用迭代器来遍历栈中的元素
//ACE_Unbounded_Stack_Iterator<DataElement*> iter(ustack);
//for(iter.first();!iter.done();iter.advance())
//{
// DataElement** element;//注意定义的是“指向指针的指针”
// iter.next(element);
// ACE_DEBUG((LM_DEBUG,ACE_TEXT("%d:",(*element)->getData())));
// delete (*element);
//}
}
};