Skip to main content
GameDev.net gamedev.net
🔒 Locked

Classes referencing each other

Started by doubleds69 Nov 18, 2004 at 10:56 PM 3 replies 1.1k views
Original Post
doubleds69
doubleds69
Hi, I'm working on an RTS game and I've run into a problem where classes reference each other, and there's also some polymorphism going on so I can't seem to get it compile with any combination of #includes and forward declarations that I can think of. Here's a simplified code snippet I made that describes the problem:

class Parent {
protected:
	Other *other;
public:
	Parent(Other *o);
	virtual ~Parent();
	virtual void Foo() = 0;
	virtual void Bar() = 0; };

Parent::Parent(Other *o) {other = o;}

Parent::~Parent() {}

class Child1 : public Parent {
protected:
	int x;
public:
	Child1(Other *o, int n);
	~Child1();
	void Foo();
	void Bar(); };

Child1::Child1(Other *o, int n) : Parent(o) {x = n;}

Child1::~Child1() {}

void Child1::Foo() {other->Blah();}

void Child1::Bar() {}

class Child2 : public Parent {
protected:
	int y;
public:
	Child2(Other *o, int n);
	~Child2();
	void Foo();
	void Bar(); };

Child2::Child2(Other *o, int n) : Parent(o) {y = n;}

Child2::~Child2() {}

void Child2::Foo() {other->Blah();}

void Child2::Bar() {}

class Other {
protected:
	Parent *P;
public:
	Other(int x);
	~Other();
	void Blah(); };

Other::Other(int x) {
	if (x == 0)
		P = new Child1(this, x);
	else
		P = new Child2(this, x); }

Other::~Other() {}

void Other::Blah() {P->Bar();}

int main() {Other o(1); return 0;}

Right now all those classes and the main method are in different files, but I could combine them however if it would help; I could also take the "Other" reference from the parent and put it into the children - it'd be messier but if it works it's worth it. If anyone can come up with a way of arranging them and such so it compiles, that would be great, but I realize it's a strange problem, I might just have to rethink how I'm doing this. Thanks a lot for any help. [edit: added source tags -SiCrane]
ekrax
ekrax
use inclusion guards in your headers.

(file1.h)
#ifndef FILE1_H
#define FILE1_H
// ...
// ... stuff
#endif
(eof)

(file2.h)
#ifndef FILE2_H
#ifndef FILE2_H
// ...
// ... blah blah
#endif
(eof)

(file3.h)
#ifndef FILE3_H
#ifndef FILE3_H
#include "file1.h"
#include "file2.h"
// ...
// ... more stuff
#endif
(eof)

(file1.cpp)
#include "file1.h"
// ...
(eof)

(file2.cpp)
#include "file2.h"
// ...
(eof)

(file3.cpp)
#include "file3.h"
// ...
(eof)

by using the #ifndef, #define, and #endif ... in your headers you can insure that each header is only includes once in your project, but also you can declare that header as many times in any source file.

hope this helps.

doubleds69
doubleds69
Actually I do have the #ifndef, #define, #endif things around the headers, I just left them out of the description to save space. Unfortunately it still doesn't work. Good thinking though, thanks.
SiCrane
SiCrane
If yout put a forward declaration to Other before the Parent class and rearrange the order of defintions like so:
class Other;class Parent {protected:	Other *other;public:	Parent(Other *o);	virtual ~Parent();	virtual void Foo() = 0;	virtual void Bar() = 0; };Parent::Parent(Other *o) {other = o;}Parent::~Parent() {}class Child1 : public Parent {protected:	int x;public:	Child1(Other *o, int n);	~Child1();	void Foo();	void Bar(); };Child1::Child1(Other *o, int n) : Parent(o) {x = n;}Child1::~Child1() {}void Child1::Bar() {}class Child2 : public Parent {protected:	int y;public:	Child2(Other *o, int n);	~Child2();	void Foo();	void Bar(); };Child2::Child2(Other *o, int n) : Parent(o) {y = n;}Child2::~Child2() {}void Child2::Bar() {}class Other {protected:	Parent *P;public:	Other(int x);	~Other();	void Blah(); };Other::Other(int x) {	if (x == 0)		P = new Child1(this, x);	else		P = new Child2(this, x); }Other::~Other() {}void Other::Blah() {P->Bar();}void Child1::Foo() {other->Blah();}void Child2::Foo() {other->Blah();}

things will compile. I'll leave splitting this up into separate header files as an exercise for the reader. :)
doubleds69
doubleds69
Awesome, that putting off the calling of the functions of the forward-declared class until after the definition was the trick. Thanks a lot.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.