object interdependence/recursivish problem

Started by
6 comments, last by rileyriley 23 years, 1 month ago
I'm in the process of creating a game, and I want all of the things that can be in the game environment to be derived from one object class, "Object". This includes Ships, Weapons, and Effects (like explosions and smoke and stuff). I would like to be able to add effects to objects. I was planning on putting a linked list of effects in the Object class so that I could add fire to a ship or something like that. The problem is this: I cannot put a linked list of Effects into an Object because the base class of Effect _IS_ Object. So the Object class can't know what Effects are until they are defined, and Effects can't be defined until Objects are completely defined. Here is the basic code for what I'm talking about: class Object {     LLNode < Effect> * effects; //the linked list of effects     //other stuff }; class Effect : public Object {     //inside stuff }; Of course if I reverse the order of these classes I get the same but converse problem. I even tried putting the line class Object; over the declartation of Effect, and putting the declaration of Object under that. It didn't give me an extra error, but it didn't fix the existing one. Is there any way to get around this? It seems like there should be, perhaps with some system of pointers? I was hoping it wouldn't be so complicated though. Thanks for any help /riley Edited by - rileyriley on February 17, 2001 1:36:09 PM
--Riley
Advertisement
I believe the problem is that your templated LLNode creates concrete instances of Effects instead of pointers to Effects. You have a bit of a "chicken & the egg" scenario here, in which you have to get around these two rules of C++:
- you cannot declare concrete members in a class that have not been defined. You can declare pointers to undefined types, or references to undefined types, but not objects of undefined types.
- you cannot derive from an undefined class.

From the second rule, you obviously must define Object before Effect; there''s no other way to do it. So that means in Object, you may only include members that are pointers or references to Object-derived types.

The following code compiles using STL''s list:
  #include <list>using std::list;class Effect; // forward declarationclass Object{  list<Effect*> m_effects;};class Effect : public Object{};  


If your templated linked list works in a similar manner to std::list, you should be able to use the same solution.

Note: as a different style, you can omit the forward declaration of ''class Effect;'' and declare the list in this way:
list&ltclass Effect*> m_effects;

Good luck.
ok, thanks a lot. I actually tried but the compiler coughed all over it so I didn''t really pursue that route. I''m using my own list class, I''ll do a bit of research on what you wrote.
--Riley
it sounds like you are making everything of the same base class so you can have a linked list of things to process in the game loop, which is good, but if each object has a linked list of Effects, the processing of those is handled under the other objects, so why does an Effect have to be treated the same way as every other object?
"Be that word our sign in parting, bird or fiend!" I shrieked, upstarting —"Get thee back into the tempest and the Night''s Plutonian shore!-just 2 of 96 lines from E.A.P.'s "the Raven"
k reading over my post it looks kind of confusing. Basically, it sounds like it would be appropriate to make the Effect class a *separate* class, because all the Effect updates will get dealt with through the other objects ANYWAYS, so you wouldn''t need to handle them directly from the game loop. Thus, they don''t need to be derived from the same base class.

Of course this is all based on the huge assumption that I''ve made, which is that you are using inheritance in this way so updating everything is easier. You might have another objective
"Be that word our sign in parting, bird or fiend!" I shrieked, upstarting —"Get thee back into the tempest and the Night''s Plutonian shore!-just 2 of 96 lines from E.A.P.'s "the Raven"
No you are quite right, and I actually thought about doing it as you suggested. But I chose to make Effects Objects as well because I want to be able to add Effects to the game environment (GamePhase) by themselves, without relying on objects. For example, if a ship gets shot once, I give it some smoke, but when it gets shot 34235 times and finally explodes, I add the Explosion to the GamePhase and delete the ship immediately. That way the Explosion can run independently of the ship.

I could still have them as completely separate classes, but it would mean having a linked list of Effects in addition to my linked list of Objects. Of course, the hassle of that is probably much less than the hassle of working out how to add Effects to themselves but hey... where''s the fun in that? hehe, thanks for your replies
--Riley
My project at the moment also has a list of Object*s and with the Object type being extended to lots of others.

It it possible that you have something like this:

class Effect; // forward dec

class Object
{
object stuff

void a_function()
{
Stuff about Effects
}
};

class Effect:public Object
{
effect stuff
};


If this is the case, the function in Object is asked to do something with Effects when it has only just heard of Effect but doesn''t know what it is. Perhaps it should be...


class Effect; // forward dec

class Object
{
List all the things in Object, and declare all the functions like this:
void a_function();
};

The above should be in a .h file which is included by the below.

void Object::a_function()
{
the function body
}

The declaration of Effect should be somewhere in between.
I haven''t explained it that well, maybe someoine can elaborate. If you want to see my code, which does some similar things, email me.
I dread having to learn C++ but I''m going to have to. Java has none of these problems, the compiler works for you, not the other way around.

This topic is closed to new replies.

Advertisement