使用 STL 算法简化代码流程





3.00/5 (4投票s)
2004 年 2 月 27 日
1分钟阅读

43125

350
本文提供了示例,展示了使用 STL 算法的优势。
引言
在 C++ 应用程序开发中,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<TContainer::iterator>(tc.begin(), tc.end(), mdel); tc.clear(); } };
TContainer
:容器类。TDelete
:删除仿函数。
使用设计的示例
以下是代码示例,演示了该设计的应用
#include "stdafx.h" #include "templdefs.h" #include <vector> #include <map> #include <string> using namespace std; //The class element for sequence container 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());} }; // The definition of concrete sequence container class and dellocator class typedef vector<CCounter*> CCounterArray; typedef TSeqDeletor<CCounter> CCounerDel; typedef TDealloc<CCounterArray, CCounerDel> CCDellocate; typedef vector<CAnimal*> CAnimalList; typedef TSeqDeletor<CAnimal> CAnimalDel; typedef TDealloc<CAnimalList, CAnimalDel> CADellocate; //The class element for associative container class CTextBook { private: string m_szTitle; public: CTextBook(char* sz):m_szTitle(sz){}; ~CTextBook(){printf("%s is completed!\n", m_szTitle.c_str());} }; // The definition of concrete associative container class and dellocator class typedef map<int, CTextBook*> CBookList; typedef TAsoDeletor<CBookList::value_type> CBookDel; typedef TDealloc<CBookList, CBookDel> CBDellocate; typedef pair <int, CTextBook*> book_pair; int _tmain(int argc, _TCHAR* argv[]) { int i; // Demonstrate the sequence container buffer release CCounterArray cntList; CAnimalList anList; char san[20]; // Create the sequence containers 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); } //Release the sequence container object; CCDellocate cntFree; CADellocate anFree; cntFree(cntList); anFree(anList); // Demonstrate the associative container buffer release 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);
如果我们使用常规方法释放容器缓冲区,代码将如下所示
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();
比较以上两种方法,第一种设计大大减少了代码量,尤其是在存在大量容器对象时,并且该设计更多地利用了面向对象编程的优势。
本文仅展示了最简单的应用案例,但本文提出的思想可以应用于更复杂的应用场景并优化设计。