• 13
• 18
• 19
• 27
• 9

# circular include hell (C++)

This topic is 4367 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Okay, I am really hating the ridiculous intricacies of these 3 classes. CEngine, CDebugConsole, CDebugConsoleEventReceiver. CEngine needs to call functions inside CDebugConsole. CDebugConsole needs to call the constructor (non-default) of CDebugConsoleEventReceiver. CDebugConsoleEventReceiver needs to call functions inside CEngine. So, CEngine includes CDebugConsole, CDebugConsole includes CDebugConsoleEventReceiver and CDebugConsoleEventReceiver includes CEngine. I don't think that there is another way I'll be able to do this. I have a forward declaration of CDebugConsoleEventReceiver in the CDebugConsole header file, but it turns out that it's not going to work because I need to call a non-default constructor. Am I completely screwed? Do I need to scrap my current design for this bit and just re-write everything?

##### Share on other sites
Quote:
 Original post by EndarI have a forward declaration of CDebugConsoleEventReceiver in the CDebugConsole header file, but it turns out that it's not going to work because I need to call a non-default constructor.
Can you not call the constructor from the CPP file, instead of the header?

If you just define the classes in the header, and don't implement any methods, there's no problem.

##### Share on other sites
also make sure you don't use the trouble classes by value in your header file..here's a quick example

Circular dependency way
// lets say this is a header file that causes// the circular dependency problem#include <foo.h>class MyClass{   public:           foo value;};

Non-circular dependency way
// forward declare the classclass foo;class MyClass{    public:       foo* value;};// make sure you include foo.h in your source file// wherever MyClass is implemented

This is what Steve is saying, I misread it the first time =)

##### Share on other sites
Quote:
 Original post by EndarOkay, I am really hating the ridiculous intricacies of these 3 classes.CEngine, CDebugConsole, CDebugConsoleEventReceiver. CEngine needs to call functions inside CDebugConsole. CDebugConsole needs to call the constructor (non-default) of CDebugConsoleEventReceiver. CDebugConsoleEventReceiver needs to call functions inside CEngine.So, CEngine includes CDebugConsole, CDebugConsole includes CDebugConsoleEventReceiver and CDebugConsoleEventReceiver includes CEngine.I don't think that there is another way I'll be able to do this.I have a forward declaration of CDebugConsoleEventReceiver in the CDebugConsole header file, but it turns out that it's not going to work because I need to call a non-default constructor.Am I completely screwed? Do I need to scrap my current design for this bit and just re-write everything?

Your whole design is not completly flawed, but there is something weird, obviously. What you want to achieve is very similar to the observer pattern, but in your case the subject creates its own observers (in fact, it creates events that will in turn call the update functions in the observer (CEngine)). A possible solution should be to use the observer pattern in a correct way:
class DebugConsoleEventReceiver{public:  virtual void update(DebugConsoleEvent *e) = 0;};class DebugConsole{  std::vector<DebugConsoleEventReceiver*> mObservers;public:  void addObserver(Observer* o) { mObservers.push_back(o); }  void fireEvent(DebugConsoleEvent *e)  {    for (size_t i=0; i<mObservers.size(); i++) {      mObservers->update(e);    }  }};class Engine : public DebugConsoleEventReceiver{  DebugConsole mConsole;public:  Engine() { mConsole.addObserver(this); }  void update(DebugConsoleEvent *e) { ... }};

HTH,