• 5293阅读
  • 0回复

【转载】用STL的算法来简化程序代码 [复制链接]

上一主题 下一主题
离线handsoft
 

只看楼主 倒序阅读 楼主  发表于: 2005-10-19
在 C++ 应用开发中,STL的算法(algorithm)能够大大降低复杂性和减少代码量。

本文讨论STL的算法用于容器所包含的对象的释放的情况, 这一简单的应用环节。

背景
STL容器类被广泛应用到C++应用中。容器包含的对象的释放的任务不是非常困难的,但是还是有大量的重复性的代码来回复制。在本文中,在容器的类型是类的指针并且是其对象用new来分配的情况下,给出一种简单的设计来管理STL容器包含的对象的释放。

设计的关键所在
首先,设计删除模板类来处理序列式容器,例如 STL vector, deque, list 类.

template<typename TType>class TSeqDeletor
{
public:
  void operator () (TType* ptr)
  {
  if(ptr)
  {
    delete ptr;
  }
  }
};
首先,设计删除模板类来处理关联式容器,像 STL map, set.

template<typename TPair>class TAsoDeletor
{
public:
  void operator () (TPair& tElem)
  {
  if(tElem.second)
  {
    delete tElem.second;
  }
  }
};
最后,用STL算法来设计函数模板来实现容器所包含的对象的释放:

template<typename TContainer, typename TDelete>class TDealloc
{
public:
  void operator()(TContainer& tc)
  {
  TDelete mdel;
  std::for_each<:iterator>(tc.begin(), tc.end(), mdel);
  tc.clear();
  }
};
TContainer: 容器类.
TDelete: 删除仿函数.
使用设计的例子
下面式例子代码来演示了这个设计的应用:

#include "stdafx.h"
#include "templdefs.h"
#include
#include
#include

using namespace std;

//序列容器的类元素
class CCounter
{
private:
  int   m_nCounter;
public:
  CCounter(int n = 0):m_nCounter(n){};
  ~CCounter(){printf("Counter %i is released!\n", m_nCounter);}
};

class CAnimal
{
private:
  string m_szAnimal;
public:
  CAnimal(char* sz):m_szAnimal(sz){};
  ~CAnimal(){printf("%s is gone!\n", m_szAnimal.c_str());}
};

// 定义具体的序列容器和其删除类
typedef vector CCounterArray;
typedef TSeqDeletor CCounerDel;
typedef TDealloc CCDellocate;

typedef vector CAnimalList;
typedef TSeqDeletor CAnimalDel;
typedef TDealloc CADellocate;


//关联式容器的类元素
class CTextBook
{
private:
  string m_szTitle;
public:
  CTextBook(char* sz):m_szTitle(sz){};
  ~CTextBook(){printf("%s is completed!\n", m_szTitle.c_str());}
};

// 定义具体的关联容器和其删除类
typedef map<int, CTextBook*> CBookList;
typedef TAsoDeletor<:value_type> CBookDel;
typedef TDealloc CBDellocate;
typedef pair <int, CTextBook*> book_pair;

int _tmain(int argc, _TCHAR* argv[])
{
  int i;

  // 演示序列容器所包含对象的释放
  CCounterArray cntList;
  CAnimalList   anList;
  char       san[20];

  // 创建序列容器
  for(i = 0; i < 20; i++)
  {
  CCounter* pct = new CCounter(i);
  cntList.push_back(pct);
  }

  for(i = 0; i < 10; i++)
  {
  memset(san, 0, 20);
  sprintf(san, "Animal%i", i);

  CAnimal* pa = new CAnimal(san);
  anList.push_back(pa);
  }

  //释放序列容器包含的对象;
  CCDellocate   cntFree;
  CADellocate   anFree;
  cntFree(cntList);
  anFree(anList);


  //演示关联容器所包含对象的释放
  CBookList     bookList;
  char       szt[40];
  for(i = 0; i < 10; i++)
  {
  memset(szt, 0, 40);
  sprintf(szt, "The Book Title of %i", i);

  CTextBook* pb = new CTextBook(szt);
  bookList.insert(book_pair(i, pb));
  }

  //Release the sequence container object;
  CBDellocate   bookFree;
  bookFree(bookList);

  return 0;
}

容器对象缓冲的释放是想当容易的,如下:

  CCDellocate   cntFree;
  CADellocate   anFree;
  cntFree(cntList);
  anFree(anList);

  CBDellocate   bookFree;
  bookFree(bookList);

假如我们用普通的方法来释放容器的buffer,代码如下:

  CCounterArray::iterator citer;
  for(citer = cntList.begin(); citer != cntList.end(); ++citer)
  {
  if((*citer))
    delete (*citer);
  }
  cntList.clear();

  CAnimalList::iterator aiter;
  for(aiter = anList.begin(); aiter != anList.end(); ++aiter)
  {
  if((*aiter))
    delete (*aiter);
  }
  anList.clear();

  CBookList::iterator biter;
  for(biter = bookList.begin(); biter != bookList.end(); ++biter)
  {
  if((*biter).second)
    delete (*biter).second;
  }
  bookList.clear();
比较上述两种方式,第一种设计更好地重用了代码,特别是有大量容器对象的情况下,减小了代码,并且设计更符合OOP.

本文仅仅展示了简单的应用情况,但是其思想可以被应用到复杂多变的设计中去。

附件为英文原版文章!
microtiger@gmail.com
快速回复
限100 字节
 
上一个 下一个