Cleanup Strategy Tutorial

This tutorial describes the cleanup strategy and provides details on alternative cleanup strategies.

Before you start, you must:

  • Deafult cleanup strategies: These are based on a template-based implementation of the strategy design pattern.

  • Alternative cleanup strategies: These can be specified as an optional template parameter of the class templates for automatic resource management.

Cleanup strategy is based on a template-based implementation of the Strategy design pattern. The strategy design pattern is one of the most popular, highly recommended design patterns. The vast majority of the competent C++ developers are already familiar with the strategy (Policy) design pattern and Policy-based design, which should improve the usability of these class templates.

Each resource management class has a default cleanup strategy that is invoked when the managing object goes out of scope. It is however possible to define an alternative cleanup strategy when constructing the managing object. It is also possible to define a custom cleanup strategy using the DEFINE_CLEANUP_FUNCTION macro.

Note: Although the examples below use LCleanedupX classes, the method for definfing how the object is cleaned up is equally applicable to LManagedX classes.

An example code snippet is given below:

       
        
       
       //Class definition of trivial R-Class
class RSimple
    {
public:

    RSimple(){iData = NULL;}

    void Open(TInt aValue)
        {
        iData = new(ELeave) TInt(aValue);
        }

    //Cleanup function – frees resource
    void Close()
        {
        delete iData;
        iData = NULL;
        }

    //Cleanup function – frees resource
    void Free()
        {
        delete iData;
        iData = NULL;
        }

    //Cleanup function – frees resource
    void ReleaseData()
        {
        delete iData;
        iData = NULL;
        }

    //static cleanup function – frees aRSimple resources
    static void Cleanup(TAny* aRSimple)
        {
        static_cast RSimple* (aRSimple)->Close();
        }
private:
    Tint* iData;

    };
      

The above RSimple class has three cleanup member functions, Close, Free and ReleaseData.

Each resource management class has a default cleanup strategy that is invoked when the managing object goes out of scope. The default cleanup strategy is dependent on the managing type. Consider the example code snippet below:

Note: Although the examples below use LManagedX classes, the method for defining a custom cleanup strategy is equally applicable to LCleanedupX classes.

       
        
       
       class CTicker : public CBase
    {
public:
    void Tick() { ++iTicks; }
    void Tock() { ++iTocks; }

    void Zap() { delete this; }

public:
    TInt iTicks;
    TInt iTocks;
    };


class CManagedUserSinglePhase : public CBase
    {
public:
    . . .

    ~CManagedUserSinglePhase()
        {
        // The iTicker manager will automatically delete the CTicker
        // The iTimer manager will automatically Close() the RTimer
        }

    . . .
private:
    // We have to use LManagedXxx for fields, not LCleanedupXxx
    LManagedPtr CTicker iTicker;
    LManagedHandle RTimer iTimer;
    };
      

The default cleanup strategy for an LManagedPtr is to delete the pointer and this is the action taken in the destructor for CManagedUserSinglePhase.

Alternate cleanup strategies are pre-defined in emanaged.h file. It is also possible to define a custom alternate cleanup strategy that can be passed as the second template parameter to the constructor of an LManagedX or LCleanedupX object.

Although the examples below use LManagedX classes, the method for defining an alternate cleanup strategy is equally applicable to LCleanedupX classes.

The default cleanup strategy is to call CTicker::Zap() function. It is possible however to define a custom alternate cleanup strategy as shown below:

       
        
       
       // Defines a custom pointer cleanup policy that calls the Zap member
template <class T>
class TTickerZap 
    {
public:
    static void Cleanup(T* aPtr)
        {
        // The general template/class scaffolding remains the same
        // for all custom cleanups, just this cleanup body varies
        aPtr->Zap();
        test.Printf(_L("Zapped CTicker\n"));
        }
    };