65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 STL 算法简化代码流程

starIconstarIconstarIconemptyStarIconemptyStarIcon

3.00/5 (4投票s)

2004 年 2 月 27 日

1分钟阅读

viewsIcon

43125

downloadIcon

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();

比较以上两种方法,第一种设计大大减少了代码量,尤其是在存在大量容器对象时,并且该设计更多地利用了面向对象编程的优势。

本文仅展示了最简单的应用案例,但本文提出的思想可以应用于更复杂的应用场景并优化设计。

© . All rights reserved.