Click here to Skip to main content
Click here to Skip to main content

Using STL algorithm to simplify the code procedure

, 26 Feb 2004
Rate this:
Please Sign up or sign in to vote.
The article gives the sample to demonstrate the advantage of using STL algorithm.

Introduction

In the C++ application development, STL algorithm shows extraordinary power to reduce the complexity and size of the code.

This article discusses it with the case of container object buffer release, the simplest application scenario.

Background

The STL container classes are widely used in C++ applications. The task of container object buffer release is not very difficult, but there are a lot of duplicated code being repeated frequently. In this article, a simple design is given out to a way to manage the STL container object buffer release in the case that the container's type is class pointer and allocated by new.

The key step of the design

First, design the deletion template to deal with sequence container, i.e. STL vector, deque, list class.

template<typename TType>class TSeqDeletor
{
public:
    void operator () (TType* ptr)
    {
    if(ptr)
    {
        delete ptr;
    }
    }
};

Second, design the deletion template to deal with associative container, like STL map, set.

template<typename TPair>class TAsoDeletor
{
public:
    void operator () (TPair& tElem)
    {
    if(tElem.second)
    {
        delete tElem.second;
    }
    }
};

Finally, design the function template to implement container buffer release with the STL algorithm:

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: the container class.
  • TDelete: the deletion functor.

The sample of using the design

The following is the code sample to demonstrate the application of this design:

#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;
}

The container object buffer release processing is fairly simple in here, just like:

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

    CBDellocate   bookFree;
    bookFree(bookList);

If we use the regular way to release the container buffer, code will be like this:

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

Comparing the above two methods, the first design dramatically reduces the code size especially when there are lots of container objects, and the design takes more advantages of OOP.

This article only shows the simplest application case, but the idea presented in this article can be applied on more sophisticated application scenarios and optimize the design.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

No Biography provided

Comments and Discussions

 
Generalmember template PinsussAnonymous26-Feb-04 22:23 
GeneralRe: member template PinsussAnonymous27-Feb-04 13:03 
GeneralRe: member template PinsussAnonymous29-Feb-04 20:45 
GeneralRe: member template PinmemberJoey1-Mar-04 5:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.141015.1 | Last Updated 27 Feb 2004
Article Copyright 2004 by Zhaohui Xing (Joey)
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid