#ifndef GLRGUARD #define GLRGUARD /** * * Class glrGuard is the base class for classes that represent the nodes of * derivation forest (glrNode class) and the vertices of graph stack (glrStateVertex class). * But generally it can be used anywhere. It provides simple semiautomatic garbagge collector. * It stores in each object number of pointers to it. If you make a copy of pointer to the * glrGuard -- type object, you should call it's shackle() function which increases * the stored number of pointers. If you forgot some pointer to the glrGuard -- type object, * you should call it's release() function before it, which decreases the stored number of pointers and * if it become 0, it calls it's own destructor. Therefore objects with the glrGuard base class * should be never deleted directly (by the delete opearator but by calling their release() * function. Of course they should never be alocated on stack. * * Important! glrGuard class has virtual destructor, which makes nothing. If you want * to get cascade deleting, when one object with glrGuard base class stores pointers * to other objects with glrGuard base class you should simpy call the release() * function of all remembered object in your own overrided virtual destructor of the first object. * */ class glrGuard { private: int numOfPointers; public: /** * * Function getNumOfPointers() returns the number of pointers which points to the object. * It is here particularly for debug reasons. * */ const int &getNumOfPointers() const { return numOfPointers; } /** * * The release() function decereases the counter of pointers to this object and * deletes object if the counter becomes 0. Call this function before * you forgot pointer to an object with base class glrGuard. * Objects with base class glrGuard * should be always dealocated using their release() function. * */ void release() { #ifdef DEBUGEXCEPTIONS if(numOfPointers<=0){ throw glrPointerCounterUnderflowException(numOfPointers); } #endif --numOfPointers; if (!numOfPointers) delete this; } /** * * Function shackle() increases stored counter of pointers to this object. * You should call it when you make a copy of the pointer to this object. * */ void shackle() { ++numOfPointers; } ; /** * * Constructor initializes the pointers counter to 1 -- you have not to call the shackle() * after creating a new object with the glrGuard base class. * */ glrGuard() { numOfPointers=1; } ; /** * * The destructor makes nothing. You should override it in your own glrGuard -- derived class * and call the release() function in it to all remembered glrGuard -- derived objects * to get the cascading delete if needed. The destructors of the glrGuard -- derived classes should be * always vitrual. * */ virtual ~glrGuard() { #ifdef DEBUGEXCEPTIONS if (numOfPointers) throw glrInvalidDeleteException(numOfPointers); #endif }; }; #endif