ACE篇之六:ACE容器之二(栈)

来源:互联网 发布:食品安全网络谣言 编辑:程序博客网 时间:2024/06/06 00:33

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);
   //}  
}
};

原创粉丝点击