Figure 4: Destruction Manager

// dmanager.h:
#include <memory>
#include <vector>

using namespace std;

class Destructor;      // forward declaration

class DestructionManager {
   typedef auto_ptr<DestructionManager> DestructionManagerPtr;

   vector<Destructor*> m_destructors;

   static DestructionManagerPtr& get_instance();

   DestructionManager() {}
   ~DestructionManager();

   friend class auto_ptr<DestructionManager>;

public:
   // singleton interface
   static DestructionManager& instance() 
   { return *get_instance(); }

   void register_destructor(Destructor* destructor)
   { m_destructors.push_back(destructor); }

   void destroy_objects();    // destroy the objects
};

// dmanager.cxx:
#include <algorithm>    // for 'sort'

#include "dmanager.h"
#include "destructor.h"

using namespace std;

DestructionManager::~DestructionManager()
{
   // the Destruction Manager is responsible for managing
   // the memory occupied by Destructor objects
   for (int i = 0; i < m_destructors.size(); ++i)
      delete m_destructors[i];
}

template <class T> class greater_ptr {
public:
   typedef T* T_ptr;

   bool operator()(const T_ptr& lhs, const T_ptr& rhs) const
   { return *lhs > *rhs; }
};

void DestructionManager::destroy_objects()
{
   // sort the destructors in decreasing order
   sort( m_destructors.begin(), m_destructors.end(),
         greater_ptr<Destructor>() );

   // destroy the objects
   for (int i = 0; i < m_destructors.size(); ++i)
      m_destructors[i]->destroy();
}