0

Okay, I understand forward declarations, but I need to call members / fields on BOTH ends in this case, so I can't use that. I tried to overwrite the declaration inside the .cpp file (by including the actual header of the class I need to use) but the pointer I defined in the header via forward declaration was broken when I tried to use it.

How can I get around this? Do you need code ?

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
pixartist
  • 1,137
  • 2
  • 18
  • 40
  • The mutual dependency you describe indicates a design flaw. Revisit your design and eliminate the tight coupling between the two types. – Captain Obvlious Nov 25 '13 at 23:00
  • 2
    An SSCCE would be lovely... http://sscce.org/ – Joe Z Nov 25 '13 at 23:00
  • Well, I have an event system. I also have a class A which contains a pointer of an Object of Class B, and manages this object. Now I want Class B to send Events, containing a pointer to Class A. Thus all classes need to know each other (except for the Event class, it only needs to know class A) – pixartist Nov 25 '13 at 23:02
  • Class B doesn't need to know the type of Class A in order to send events to it. Use dependency injection. Make Class A derive from a class called "EventReceiver", and then store a pointer to the EventReceiver in Class B. See [the Observer pattern](http://en.wikipedia.org/wiki/Observer_pattern) – Taylor Brandstetter Nov 25 '13 at 23:04
  • The events are not handled by either A or B. Class B needs to know "Event". "Event" needs to know class A. Class A needs to know class B. – pixartist Nov 25 '13 at 23:07
  • And why does Event need to know class A? – Taylor Brandstetter Nov 25 '13 at 23:08
  • Because class A contains a field which the Event requires. (Class A contains a player and other info, which is used by the event for logging & identification, Class A is a gamecontroller and class B is the game logic) – pixartist Nov 25 '13 at 23:10

2 Answers2

3

You need to keep in mind that forming a pointer to a class only requires a declaration of that class, while accessing that class's members requires its definition. So to solve circular dependencies, you can do this:

A.hpp

class B;

class A
{
public:
  int foo(B *b);
  int bar();
};

B.hpp

class A;

class B
{
  A *m_a;
public:
  int foo();
  explicit B(A *a) : m_a(a) {}
};

A.cpp

#include "A.hpp"
#include "B.hpp"

int A::foo(B *b)
{
  return 2 * b->foo();
}

int A::bar()
{
  return 42;
}

B.cpp

#include "A.hpp"
#include "B.hpp"

int B::foo()
{
  return m_a->bar();
}
Angew is no longer proud of SO
  • 167,307
  • 17
  • 350
  • 455
0

If you're the only one that will have access to the inside of the code (like when you're doing a project for yourself, alone, or distributing a closed .lib/.dll), and you're sure you need your classes to include themselves in a circular way, you could always use an abstract base class.

class base{};

class A: public base{
   base *bMember;
};

class B: public base{
   base *aMember;
};

That's a bit of a bad practice, but if you need a straight solution, it should be sufficient. A better way would be to fix the dependencies or use separate base classes.

Paweł Stawarz
  • 3,952
  • 2
  • 17
  • 26
  • Even if he did really need to do this, why wouldn't forward declarations suffice? I don't see the point of the abstract base class. – Taylor Brandstetter Nov 25 '13 at 23:06
  • Some older IDE's tend to ignore forward declarations. I had a problem like that when I was doing a project long ago with some version of VS. – Paweł Stawarz Nov 25 '13 at 23:08