Boost logo

Boost :

From: Michael Goldshteyn (mgoldshteyn_at_[hidden])
Date: 2005-11-16 13:56:00


I have a class hierarchy which unfortunatelly results in circular
dependencies not allowed by C++. Is there any simple way to fix this? Please
note, I have trivialized this problem for the purpose of illustration. The
actual code that needs this is far more complex. I am quite perplexed,
please help:

Here is the code made as simple as I can:

class Part

// The Action class is where the problem arises. It depends on an iterator
in a class which is not yet defined.
// The class cannot be defined before the Action class, because it depends
on the definition of the Action class.
class Action
  typedef std::list<Part> PartsList;

  // I want a back "reference" to the iterator pointing to
  // the part for which this action applies. This is OK, I can just
  // typedef PartsList myself and don't need Whole for this
  PartsList::iterator iPart;

  // I also want a back "reference" all the way to the iterator
  // in the NameWholeMap for whose value this action applies
  // Here, I have a circular reference issue.
  // Note: Storing the key in the NameWholeMap to eliminate
  // this problem is not an option. I need a direct reference back
  // to the association in the map (map iterator), so as not to have
  // to look it up again.
  NamedWholes::NameWholeMap::iterator iNamedWhole;

// Whole is basically a container of Parts. Action needs an iterator to the
list it contains.
// Fortunatelly, because the value in this list (i.e. Part) does not depend
on Action, I can just
// type define the same list (i.e. PartsList) in the Action class and refer
to its iterator there.
class Whole
    typedef std::list<Part> PartsList;
    typedef boost::optional<Action> OptionalAction;
    typedef std::vector<Action> Actions;

    void GetActionsOnSomePartsForThisWhole(Actions &actions);

    OptionalAction DecideOnAction() const;

    Parts m_parts;

// This is the other half of our circular reference problem. This class has
a function which gathers
// actions on various parts contained in various wholes contained in its
NameWholeMap. Those
// actions would like to know directly which iterator in the NameWholeMap
they were created
// from, so as not to require a search by key later.
// The problem is that this class must know how Action is defined and Aciton
must know how
// this class is defined, creating a circular reference.

class NamedWholes
    typedef std::map<std::string,std::Whole> NameWholeMap;
    typedef Whole::Actions Actions;

    void GetAllActions(Actions &actions);

    NameWholeMap m_nameWholeMap;

Boost list run by bdawes at, gregod at, cpdaniel at, john at