Jump to content
  • Advertisement
Sign in to follow this  
polaris2013

Circular Dependence + Inheretance

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

If you intended to correct an error in the post then please contact us.

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
//#if !defined HEADER_PUREABSTRACT
#define 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
//#if !defined HEADER_DERIVED1
#define HEADER_DERIVED1

#include "PureAbstract.h"

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

	CDerived1(void);
	~CDerived1(void);
};
#endif
Derived2.h
#ifndef HEADER_DERIVED2
//#if !defined HEADER_DERIVED2
#define 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 this post


Link to post
Share on other sites
Advertisement
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
Share on other sites
Quote:
Original post by ChaosEngine
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 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 this post


Link to post
Share on other sites
Quote:
Original post by Hodgman
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.


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...)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!