views:

131

answers:

5

I have the following cyclic dependency problem I am trying to solve:

typedef std::map<int, my_class> my_map;

class my_class {
...
private:
    my_map::iterator iter;
};

class otherclass{
public:
    my_map::iterator getIter(); 
private:
    my_map map;
};

The compiler does not like this, since my_class was not declared before the typedef.

if I try to forward-declare myclass like this:

class my_class;

typedef std::map<int, my_class> my_map;

class my_class {
...
private:
    my_map::iterator iter;
};

class otherclass{
public:
    my_map::iterator getIter(); 
private:
    my_map map;
};

I get an "error: forward declaration of 'my_class'".

How can I break this vicious cycle?


I'm sorry but I have to revise my question, as I have noticed that my representation is slightly wrong.

The following is the correct representation of my problem:

class my_container;

typedef std::map<int, my_container> my_map;

class my_class {
...
private:
    my_map::iterator iter;
};

class my_container {
public:
    my_class a_method();
private:
    vector<my_class> v;
};

class otherclass{
public:
    my_map::iterator a_method();
    my_class another_method();
    my_container yet_another_method();
private:
    my_map map;
};

Sorry about this

A: 

put my_map as a member in my_class, like this:

class my_class {
public:     typedef std::map<int, my_class> my_map;
...
private:
        my_map::iterator iter;
};

class otherclass{
public:
        my_class::my_map::iterator getIter(); 
private:
        my_class::my_map map;
};

If you don't want to always use my_class::, then make another typedef.

tenfour
A: 

You could put the typedef inside my_class:

class my_class {
public:
    typedef std::map<int, my_class> my_map;
...
private:
    my_map::iterator iter;
};

class otherclass{
public:
    my_class::my_map::iterator getIter(); 
private:
    my_class::my_map map;
};
FireAphis
yep, this should work, but unfortunately I made a mistake formatting my question, and my situation is a bit more complicated. Please see post.
izex
+2  A: 
class my_class;

typedef std::map  < int, my_class* > my_map;
                      ~~~~~~~~~~ use pointer here!
Todd
Please do not use pointers. This will just lead to leaks as you are not explicitly defining the ownership of the objects.
Martin York
+1, though this assumes you don't *want* adding this to the map to cause a copy. That's generally true, though. @izex, do you really need intend to create a full copy of the object every time you put it in the map or read it from the map? That typically is quite expensive. As an aside, I've grown to really like shared_ptr<> for this problem: typedef std::map < int, shared_ptr<my_class> > my_map; It just cleans up the memory management headache of using a raw pointer here.
Rob Napier
+1  A: 

Circular dependencies are generally a Bad Thing. Can you re-think your design a bit? Does a my_class really need to know what its container is?

If that's not practical, instead of an iterator into my_map, could you get away with just a my_container*? The compiler won't have a problem with using an incomplete type for the pointer.

Kristo
Thanks. I know it is not trivial, but in my case the circular dependency is necessary.I solved the problem usin a my_container* indeed.
izex
A: 

How about:

#include <map>

class my_class;                         // forward declare the type.
typedef std::map<int, my_class> my_map;

class my_class
{
  private:
    my_map::iterator iter;
};

class otherclass
{
  public:
    my_map::iterator getIter();
  private:
    my_map map;
};
Martin York