|
Boost : |
From: Michael Goldshteyn (mgoldshteyn_at_[hidden])
Date: 2005-11-16 13:56:00
Description:
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:
part.h
------
class Part
{
};
action.h
--------
// 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
{
public:
typedef std::list<Part> PartsList;
private:
// 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.h
--------
// 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
{
public:
typedef std::list<Part> PartsList;
typedef boost::optional<Action> OptionalAction;
typedef std::vector<Action> Actions;
void GetActionsOnSomePartsForThisWhole(Actions &actions);
private:
OptionalAction DecideOnAction() const;
Parts m_parts;
};
namedwholes.h
----------------
// 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
{
public:
typedef std::map<std::string,std::Whole> NameWholeMap;
typedef Whole::Actions Actions;
void GetAllActions(Actions &actions);
private:
NameWholeMap m_nameWholeMap;
};
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk