• 13
• 27
• 9
• 9
• 20

# Circular Dependence + Inheretance

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

## Recommended Posts

I think the general procedure for a circular dependence is to write a forward declaration (if Wikipedia is to be trusted). This seems to work unless the class requiring the forward declaration has other classes which are inherited from it. Up until this point I haven't had any forays into circular dependence, so when I tried it out I was getting a lot of errors "base class undefined". I found that I could get it to compile again by either (1) removing the circular dependence, or (2) moving the circular dependence to the leaf classes. Unfortunately, if I have to move the dependence to the leaf class, then what is the point of having this parent class when the shared code can't be shared? So I created a test project just to test if the circular dependence in a parent class was the problem or if it was some forward declaration that I had missed. The result is that either I did the same thing wrong twice or this just can't be done. I had the same problem in my test project as in my original project. So am I correct? Or did I do the same thing wrong twice? Well, I guess if I did the same thing wrong twice, I better post my test project so someone can identify the problem (just the headers): Parent Class:
#ifndef HEADER_PUREABSTRACT

#include "Derived1.h"
class CDerived1;

class CPureAbstract
{
public:
virtual int ImaVirtualFunction(void); //=0;
protected:
CPureAbstract(void);
~CPureAbstract(void);
};
#endif

Derived1.h
#ifndef HEADER_DERIVED1

#include "PureAbstract.h"

class CDerived1 : public CPureAbstract
{
public:
int ImaVirtualFunction(void);

CDerived1(void);
~CDerived1(void);
};
#endif

Derived2.h
#ifndef HEADER_DERIVED2

#include "PureAbstract.h"

class CDerived2 : public CPureAbstract
{
public:
int ImaVirtualFunction(void);

CDerived2(void);
~CDerived2(void);
};
#endif

In my original project, the circular dependence is more of a pointer to a container class. The CActor class has a pointer to the CActorContainer class (well, I would like for it to).

##### Share on other sites
Usually I deal with circular references in this fashion:

CManager.h
class CManagedObject;class CManager{...}#include "CManagedObject.h"

CManagedObject.h
#include "CManager.h"class CManagedObject{...}

It works for me, and is pretty simple. It can also be applied to circular nesting.

##### Share on other sites
Quote:
 Original post by polaris2013#ifndef HEADER_PUREABSTRACT#define HEADER_PUREABSTRACT#include "Derived1.h"class CDerived1;

You seem to be including the header for the derived class *and then* adding a forward declaration for the derived class (which will basically be ignored, because the full class declaration has already been included).

You only want either a forward declaration, or a full include, not both. Try commenting out #include "Derived1.h"

##### Share on other sites
As a general design rule, your base class should have no knowledge of it's derived classes. In the example, you've shown there, CPureAbstract (you can drop the "C" btw, it's completely unnecessary) knows nothing about CDerived. Neither the include nor the forward declaration are necessary.

##### Share on other sites
Quote:
 Original post by ChaosEngineAs a general design rule, your base class should have no knowledge of it's derived classes. In the example, you've shown there, CPureAbstract knows nothing about CDerived. Neither the include nor the forward declaration are necessary.
I'm guessing the dependency isn't needed here coz it's just a test. Some info on the OP's actual problem would show us if there is a real requirement for this dependency.

It's a good general rule, but there's always an exception ;) Such as a tree-structure which has nodes that can have children (CGroupNode) and nodes that don't (CNode). CGroupNode is a CNode, but a CNode has a link to a parent, which is either null or a CGroupNode.

##### Share on other sites
Quote:
 Original post by HodgmanIt's a good general rule, but there's always an exception ;) Such as a tree-structure which has nodes that can have children (CGroupNode) and nodes that don't (CNode). CGroupNode is a CNode, but a CNode has a link to a parent, which is either null or a CGroupNode.

CNode doesn't need to know that its parent is a CGroupNode, since a CGroupNode is a CNode, and CNode can store its parent as another CNode. (I know there are always exceptions, but this doesn't need to be one of them, not that is has anything to do with the original question...)