cyclic dependencies
Frank Drebin

how can i solve this problem:

//file1.cpp

class a
{
public:
void do_something_with_b();
};

void a::do_something_with_b()
{
b.do_something();
}

//file2.cpp

class b
{
public:
void do_something_with_a();
};

void b::do_something_with_a()
{
a.do_something();
}

Thomas Fjellstrom

put the class declaration in thier own .h file, and include then where needed.

mEmO

Are you sure you're not confusing class declarations and objects? A class is a template for an object, not the object itself. To use it properly, do like this:

class Foo
{
 public:

 int var;
};

Foo bar;
bar.var = 2;

Just to make sure, though.

Torbjörn Josefsson

There's No way to protect against this kind of 'logical bug'

Simply don't write the program in this way.

It's the same thing as writing:

void do_something(){
   do_something();
}

It's a recursive situation without any exit condition.

If you want to make sure each one is only called once (I'm not sure what you're trying to do), you have to perform a check to see that it doesn't continue forever - maybe pass along an integer counter in the call, increment it for each call, and see if it exceeds some max value for recursive calls?

Frank Drebin

perhaps the example i gave is not very well
but i found a solution for this:
just put all header files of the classes in one big header file and include this file in every sourcefile so that each class knows the others

Thomas Harte

So, you're problem was not one of functions calling each other, but one where the first class didn't know the definition of the other? Don't forget that you can use forward defintions, like :

class Elephant;

class Mouse
{
   ...
   Elephant *ScaredCreature;
   ...
};

class Elephant
{
   ...
   Mouse *ScaryCreature;
   ...
};

i.e. if the compiler really only needs to know that Elephant exists as a class (rather than being fussed about members), then that is all you need to tell it.

You know how I found that out? I had a little hunchback at the office.

Frank Drebin

yes with a pointer to a class this may work but when you declare a variable of that class it doesn't
like this:

class Elephant;

class Mouse
{
...
Elephant ScaredCreature;
...
};

class Elephant
{
...
Mouse ScaryCreature;
...
};

X-G

Frank Drebin said:

yes with a pointer to a class this may work but when you declare a variable of that class it doesn't

There's a good reason for that. For one thing, each of the resulting classes would be infinitely large, as they contain each other. ::)

Frank Drebin

so how can i break a dependencie like that:
the class player needs to know the class bullet (and its firing method) and the bullet needs to know about the player (for collision detection)

X-G

Obviously, your only chance is to use pointers.

gillius

If you need A to know about B and B to know about A you CANNOT have A contain B and B contain A. That makes no sense and it would go on forever.

You must use pointers or references and you must use forward delcarations as was shown to you earlier. Do not place all classes in one big header or whatever you were considering. In your class header, instead of doing #include "Class.h", replace it with class Class; as much as possible. As long as the class you are defining does not inherit from Class, does not contain a Class object, and does not have any methods taking a copy of a Class object (ie only Class* and Class& are seen), you can and should use forward declarations.

miran

And of course you should use include guards (or whatever they're called):

1//file Enemy.h
2#ifndef ENEMY_H
3#define ENEMY_H
4 
5class Bullet;
6class Enemy {
7 protected:
8 list <Bullet *> bullets;
9 
10 public:
11 // whatever
12};
13 
14#endif //ENEMY_H
15 
16 
17 
18//file Bullet.h
19#ifndef BULLET_H
20#define BULLET_H
21 
22class Enemy;
23class Bullet {
24 protected:
25 Enemy *parent;
26 
27 public:
28 // whatever
29};
30 
31#endif //BULLET_H

Frank Drebin

o.k. but i'm not very good in pointers, so when i just declare a pointer to the bullet class in the player class how can i call then the bullet.fireit() method ???

23yrold3yrold
Quote:

o.k. but i'm not very good in pointers, so when i just declare a pointer to the bullet class in the player class how can i call then the bullet.fireit() method

Well, first you need to create a bullet (using new), but I'm sure you knew that. Then you can call
bullet->fireit().

Frank Drebin

1. so i can use
"pointer_to_bullet=new bullet;" and
"pointer_to_bullet->fireit();"
in the player.cpp code without having declared
the class bullet before
(just forward declaration like "class
bullet;") ???

2. and when theres a global object bullet1
i can use
"pointer_to_bullet=&bullet1;" and
"pointer_to_bullet->fireit();"
... ???

23yrold3yrold

1. No. You need to have declared the class, not just a forward declaration (I call these class prototypes as they are like function prototypes. I may be the only person that does that, though ;)). If you don't declare the class, how is it going to know that it has a member function called fireit()?

You can organize it like this, just as an example:

1class Bullet
2{
3 void fireit();
4};
5 
6Bullet* somefunction()
7{
8 Bullet* b = new Bullet;
9 b->fireit();
10 return b;
11}
12 
13void Bullet::fireit()
14{
15 // whatever
16}

You can define fireit() (and all of Bullet's other functions) in a seperate file if you want. But if you want to access Bullet's members, you must declare the members first.

2. Sounds right ....

X-G

Creepy Disembodied Bearded Tycho Head said:

I call these class prototypes

You should call them classes, simple enough. ;)
Once you instantiate it, it's an object. Class is to object what prototype is to function, one could say. I think. ;)

23yrold3yrold

Nonono ...

   // class prototype
   class Bullet;

   // class declaration
   class Bullet
   {
      public:
         Bullet();
         ~Bullet();
         void fireit();
   };

   // class definition
   Bullet::Bullet(){
      // blah blah blah
   }

   Bullet::~Bullet(){
      // blah blah blah
   }
   void Bullet::fireit(){
      // blah blah blah
   }

Geddit?

X-G

How interesting, then, that there are no such in the code snippet. ;)

23yrold3yrold

Huh? Look at Frank's last post. I know I didn't use one; it wouldn't have worked. That was the point ;)

X-G

Just call them forward declarations like everyone else, all right? ;)

23yrold3yrold

I called one thing a class prototype, and another thing a class declaration. Which one is the forward declaration, can we call function prototypes that, and what do you call the other class thing (whichever isn't a declaration)?

X-G

s/class prototype/forward declaration of class x/

Thread #234247. Printed from Allegro.cc