Structs Problem

Pages: 12
Hi there.

I'm having a problem with some structs in a program I am writing. What I am trying to do is use pointers to a struct type within a struct that uses that type as well. For example:

struct struct2;

struct struct1
{
struct2 * struct2_pointer;
}


struct struct2
{
struct1 * struct1_pointer;
}

This ability is a new concept to me, for two structs to have access to one another. Before I though that if for example struct1 knew struct2, then struct2 couldnt know struct1, but then I read about adding the "struct scruct1;" line so that it could know it.

Anyways, that is a primer for the problem I am having. Here is my actual code:


#ifndef _CREATURE_EFFECT_H
#define _CREATURE_EFFECT_H 1



#include "EFFECT_TEMPLATE.h"
#include "CREATURE.h"

struct CREATURE;


struct CREATURE_EFFECT
{
CREATURE_EFFECT()
{
reset();
}
bool active;
EFFECT_TEMPLATE * effect_template;
EFFECT_DURATION duration;
CREATURE * creature;
unsigned last_time[3];
void reset()
{
effect_template = NULL;
duration.reset();
active = false;
for (int x=0;x<ACTIONS_PER_EFFECT;x++)
last_time[x] = 0;
}
void set(EFFECT_TEMPLATE * new_effect_template, CREATURE * new_creature)
{
effect_template = new_effect_template;
creature = new_creature;
duration.set(&effect_template->duration,&creature->adjusters,
effect_template->id.type);
active = true;
}
bool update()
{
if (active && duration.reached())
{
reset();
return true;
}
return false;
}
bool actions_ready(int x)
{
return effect_template->actions.action[x].ready(&last_time[x]);
}
};



#endif


My problem is that when I debug the code, it gives me an error in the "set" method, at the line "duration.set(&effect_template->duration,&creature->adjusters,effect_template->id.type);". It says that CREATURE is an undefined type, although it has no problem with the "CREATURE * creature;" line at the top of the struct, and no problem with the "creature = new_creature;" line within the set method. Any ideas what might be causing this?
creature->adjusters

The complier doesn't know about CREATURE's member adjusters. Define the whole CREATURE class before you try using it's members.
Last edited on
How do I do that? CREATURE is defined in CREATURE.h.
Post code which produces the error but also compilable and short.
I guess I'll try a different forum
Just out of curiosity, could you post a link to the other forum you ask this question, so I can see how others can help you.
I don't know what you expect, I provided a pretty simple problem and explained it the best I could, there's really nothing else I could show you. If you don't know what the problem is related to thats fine but dont tell me to "Post code which produces the error but also compilable and short" because it won't compile in the first place. You said earlier that I need to define CREATURE but when I asked you to explain that you opted not to.
Sorry, but you didn't post "EFFECT_TEMPLATE.h" and more importantly "CREATURE.h" where, as you say, CREATURE class is defined and as there is a problem with the CREATURE class, it is essential to know how it is implemented.
Try posting "CREATURE.h", see if there is a problem with that.

Also, why are you forward declaring CREATURE after it's already defined in "CREATURE.h"?
I can assure you that there is no problem with CREATURE.h or EFFECT_TEMPLATE.h, this problem didn't show up until I tried giving CREATURE_EFFECT access to the CREATURE struct. The problem is CREATURE has access to CREATURE_EFFECT, so I read somewhere that I needed to add the line "struct CREATURE;" so that CREATURE_EFFECT could know what CREATURE is... I don't really understand how this works, it is a new concept to me, but it comes down to wanting multiple classes to know each other. If I don't add the line "struct CREATURE;", it has no idea what CREATURE is and gives me errors everytime CREATURE is used in CREATURE_EFFECT
this is the top of CREATURE.h, I wont copy all the methods into here tho:

#ifndef _CREATURE_H
#define _CREATURE_H 1

#include "DAMAGE.h"
#include "SPRITES_GLOBAL.h"
#include "SPIRIT.h"
#include "ANIMATION.h"
#include "BODY.h"
#include "CREATURE_EFFECTS.h"
#include "CREATURE_SPELLS.h"
#include "LIFE.h"
#include "CONDITIONS.h"
#include "EFFECTS_GLOBAL.h"
#include "ADJUSTERS.h"
#include "PORTALS.h"



struct CREATURE
{
CREATURE()
{
number = -1;
active = false;
life.text_bubbles.body = &body;
team = -1;
}
int team;
int number;
bool active;
char name[32];
BODY body;
LIFE life;
DAMAGE jump_damage;
SPIRIT spirit;
CREATURE_EFFECTS effects;
CREATURE_SPELLS spells;
ANIMATION animation;
CONDITIONS conditions;
REQUIREMENTS_PARAMETER requirements_parameter;
ADJUSTERS adjusters;
static PORTALS * portals;


--------------------------------------------------------------------------------


CREATURE_EFFECTS is the class that stores CREATURE_EFFECT classes
I'm gonna be honest, I don't know what causing your problem.
I made this short test from the code you posted :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ADJUSTERS {};

struct CREATURE {
    ADJUSTERS adjusters;
};

struct CREATURE;

struct CREATURE_EFFECT {
    CREATURE *creature;
    void set() {
        ADJUSTERS *i = &creature->adjusters;
    }
};


int main() {
    CREATURE_EFFECT e;
    e.set();
    return 0;
}


It compiles fine for me (except the unused variable warning).
See if you can find anything different in your and my code.
Last edited on
try giving CREATURE a CREATURE_EFFECT variable
Ok, I think I have a solution.
Move the CREATURE_EFFECT::set() body into a source file .

source file :
1
2
3
4
5
#include "CREATURE_EFFECT.h"

void CREATURE_EFFECT::set() {
    ADJUSTERS *i = &creature->adjusters;
}


header file:

1
2
3
4
struct CREATURE_EFFECT {
    CREATURE *creature;
    void set();
};


This is how I modified my test code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ADJUSTERS {};

struct CREATURE;

struct CREATURE_EFFECT {
    CREATURE *creature;
    void set();
};

struct CREATURE {
    CREATURE_EFFECT ceff;
    ADJUSTERS adjusters;
};

//CREATURE_EFFECT.cpp file

void CREATURE_EFFECT::set() {
    ADJUSTERS *i = &creature->adjusters;
}

int main() {
    CREATURE_EFFECT e;
    e.set();
    return 0;
}

**DELETED


Ok, your solution seems to work, it is confusing to me though, why does it want the set definition in a seperate source file?
Last edited on
Because you are using information (member variable 'adjusters'), which is only available in the definition of the class, so the struct definition needs to be visible for complier when it compiles CREATURE_EFFECT::set().
Thanks for helping me with that! I've got one other problem now though.

I have a struct named EFFECT_ACTION, which has a set of many ACTION's (ACTION being another struct). Compiler is telling me now that ACTION is not defined. I dont think that the code for EFFECT_ACTION is important to show you because it is simply what i decribe, but here is ACTION.h:

#ifndef _ACTION_H
#define _ACTION_H 1


#include "REQUIREMENTS.h"
#include "DAMAGE.h"
#include "EFFECT_TEMPLATE.h"
#include "PORTAL_TEMPLATE.h"

//struct EFFECT_TEMPLATE;
//struct PORTAL_TEMPLATE;


struct ACTION
{
ACTION()
{
reset();
}
bool active;
REQUIREMENTS requirements;
bool jump;
int enchantment_removal;
int hex_removal;
int steal_health;
int steal_energy;
DAMAGE damage;
COMPONENTS_2D push;
//EFFECT_TEMPLATE * effect_template;
//PORTAL_TEMPLATE * portal_template;
int heal;
int energy;
int sacrifice;
unsigned burn;
unsigned freeze;
unsigned stun;
bool extinguish;
bool melt;
bool unstun;
void reset()
{
active = false;
jump = false;
enchantment_removal = 0;
hex_removal = 0;
steal_health = 0;
steal_energy = 0;
damage.reset();
heal = 0;
energy = 0;
sacrifice = 0;
requirements.reset();
burn = 0;
extinguish = false;
freeze = 0;
melt = false;
stun = 0;
unstun = false;
push.reset();
//effect_template = NULL;
//portal_template = NULL;
}
};



#endif


I have commented out the EFFECT_TEMPLATE and PORTAL_TEMPLATE stuff, because that is the root of the problem. Only leaving the include lines for EFFECT_TEMPLATE and PORTAL_TEMPLATE at the top, the error still exists. Let me explain how EFFECT_TEMPLATE is build. It has an EFFECT_ACTIONS type, which is comprised of EFFECTS_PER_ACTION number of EFFECT_ACTION types. EFFECT_ACTION like said before is comprised of ACTION types. So it looks like this: EFFECT_TEMPLATE->EFFECT_ACTIONS->EFFECT_ACTION->ACTION. For some reason it doesnt like when I try to give ACTION access to EFFECT_TEMPLATE. PORTAL_TEMPLATE is similiar to EFFECT_TEMPLATE but it goes one level higher and has it's own EFFECT_TEMPLATE pointer within it. I don't know where to begin with solving this problem, would I need to take all methods definitions out of every header file and put them into .cpp files?
Last edited on
Wow, you have some very big/complicated project going on.

I don't know where to begin with solving this problem, would I need to take all methods definitions out of every header file and put them into .cpp files?


It is usually good practice to keep the implementation separated from the definition for two reasons :
1. Makes compiling faster.
2. Makes your code more readable (to others).
If you define your functions in the implementation then the complier automatically tries to inline them just like if they were defined with the keyword inline.

Try put your functions into separate cpp files, then if the problem is still present, try rethink your class hierarchy. It's usually a bad practice to have cross references (but there are cases where it's the only solution).
Ok, I'll try that. I have quite extensively thought out my class heirarchy, and it's at a point where it is very powerful and well organize. I think it's pretty good right now, and I think I am running into some of those rare cases where cross referencing is needed. Thanks for your help. I won't mark this thread solved until I seperate my implementation and see that it solves the problem.
btw seperated implementation makes my code compile slower..
btw seperated implementation makes my code compile slower..


Really?
Do you compile every cpp file every time, even if it is not changed? The object (.o) files don't depend on the other object files, so if a cpp wasn't changed then you don't have to recompile it (just link it).
Pages: 12