本文共 3549 字,大约阅读时间需要 11 分钟。
http://hi.baidu.com/qingshanyin/blog/item/4c487e50c740f8648535249e.html
前沿:为了跨平台的需要,以及性能考虑,ACE创建了自己的容器。ACE支持两种容器:基于模板的、类型安全的容器,以及基于对象的容器。
基于模板的容器:允许在编译时创建“针对特定类型的容器”;基于对象的容器:支持某一类对象类型的插入和删除。
ACE的容器包含两类:序列容器和关联容器。
序列容器是一种其元素按照线性顺序排列的容器。由于要在容器中进行迭代,各个元素的顺序不会改变。列表、栈、队列、数组和集合都是ACE的一些类所代表的序列的例子。
1、双向链表
双向链表在序列中同时维护有向前和向后的链接,从而可以在序列中进行高效的向前和向后遍历。但不能对元素进行随机访问。
ACE_DLList是ACE提供的双向链表。它是一个基于模板的容器,所以我们需要预先指定我们的列表中使用的元素的类型。
2、双向链表测试代码
(1)双向链表元素定义:DataElement(DataElement.h)
//DataElement元素有一个很好的特性:即它会记住自己现在有多少个实例
//双向链表测试,以下定义的是链表元素类型 class DataElement { friend class DataElementEx;public: DataElement(){count_++;}
DataElement(int data):data_(data){count_++;}
DataElement(const DataElement& e)
{ data_=e.getData(); count_++; } DataElement& operator=(const DataElement& e) { data_=e.getData(); return *this; } bool operator==(const DataElement& e) { return this->data_==e.data_; }~DataElement(){count_--;}
int getData(void)const{return data_;}
void setData(int val){data_=val;}
static int numOfActiveObjects(void){return count_;}
private:
int data_; static int count_; }; (2)测试类定义:ListTests(ListTests.h)#pragma once
#include "ace/Containers.h" #include "DataElement.h" //双向链表测试 //双向链表支持前向和后向迭代 typedef ACE_DLList<DataElement> MyList;//该容器可以存储元素对象,也可以存储指向对象的指针 class ListTests { public: ListTests(void); ~ListTests(void); int run(void); // 显示列表 void displayList(MyList& list); // 销毁对象 void destoryList(MyList& list); }; (3)测试类实现(ListTests.cpp)#define ACE_NTRACE 0
#include "ListTests.h"
int DataElement::count_=0;//必须对静态成员进行初始化 ListTests::ListTests(void) { }ListTests::~ListTests(void)
{ }int ListTests::run(void)
{ ACE_TRACE (ACE_TEXT("ListTest::run"));//创建一个列表,插入100个元素
MyList list1; for(int i=0;i<100;i++) { DataElement *element; ACE_NEW_RETURN(element,DataElement(i),-1);//注意:存放在容器里面的是指向元素的指针,而不是元素本身
//这意味着,当列表出作用域时候,需要负责删除元素本身,否则数据元素将 //在堆上继续存在,否则会造成内存泄漏 list1.insert_tail(element); } //迭代显示列表 this->displayList(list1); ACE_DEBUG((LM_DEBUG,ACE_TEXT("#of live objects:%d/n"),DataElement::numOfActiveObjects())); //从调试情况来看,数目为100 //创建list1的一个拷贝 MyList list2; list2=list1;//此处为浅拷贝 //迭代显示拷贝列表的内容 this->displayList(list2); ACE_DEBUG((LM_DEBUG,ACE_TEXT("#of live objects:%d/n"),DataElement::numOfActiveObjects())); //从调试情况来看,对象数目仍然是100 //清除拷贝列表和其所有元素 //因为两个列表有相同的元素, //这将导致list1包含的指针所指向的数据元素已经被销毁。 this->destoryList(list2);ACE_DEBUG((LM_DEBUG,ACE_TEXT("#of live objects:%d/n"),DataElement::numOfActiveObjects()));
//从调试情况来看,对象数目为0//所有列表本身将在此被清理。注:列表析构函数将销毁任何列表拷贝,无论其包含什么数据
//因为在这种情况下,列表包含指向数据元素的指针,此处是销毁这些数据元素的唯一机会。 return 0; }// 使用迭代器,显示列表
void ListTests::displayList(MyList& list) { ACE_TRACE(ACE_TEXT("ListTest::displayList")); ACE_DEBUG((LM_DEBUG,ACE_TEXT("Forword iteration/n"))); //前向迭代器 ACE_DLList_Iterator<DataElement> iter(list); while(!iter.done()) { ACE_DEBUG((LM_DEBUG,ACE_TEXT("%d:"),iter.next()->getData())); iter++; } ACE_DEBUG((LM_DEBUG,ACE_TEXT("/n")));ACE_DEBUG((LM_DEBUG,ACE_TEXT("Reverse Iteration /n")));
//后向迭代器
ACE_DLList_Reverse_Iterator<DataElement> riter(list); while(!riter.done()) { ACE_DEBUG((LM_DEBUG,ACE_TEXT("%d:"),riter.next()->getData())); riter++; } ACE_DEBUG((LM_DEBUG,ACE_TEXT("/n"))); }// 销毁对象
void ListTests::destoryList(MyList& list) { ACE_DLList_Iterator<DataElement> iter(list); while(!iter.done()) { delete iter.next();//析构元素,避免内存泄漏 iter++; } }(4)入口函数
// Container_Practice.cpp : 定义控制台应用程序的入口点。
// #define ACE_NTRACE 0#include "ace/Containers.h"
#include "ListTests.h" typedef ACE_DLList<DataElement>MyList; int ACE_TMAIN(int argc, ACE_TCHAR* argv[]) { ListTests listtest; listtest.run();return 0;
}转载地址:http://vvgxi.baihongyu.com/