Archived

This topic is now archived and is closed to further replies.

Kevinator

A number of questions about structs within structs.

Recommended Posts

Kevinator    229
Okay.. I am learning about stuctures in C++ so I decided to write a small piece of code that might belong in an RPG. To do this, I wrote a structure to define what the separate armor pieces are, and another structure to define the attributes of each piece of armor. So.. I decided to have the members of the first structure to be of the type that the attributes are, (if that makes sense), and I have a few questions pertaining to my code. Here it is:
  #pragma hdrstop

#include <condefs.h>
#include <iostream.h>
#include <math.h>
#include <conio.h>
#include <cstdlib.h>

#pragma argsused

struct armor_attributes
{
        int price;
        int durability;
        int weight;
        int protection;
};

struct armor        //All the different types of armor (for the player

{                              //and AI too!

        armor_attributes helmet;
        armor_attributes neck_guard;
        armor_attributes r_shoulder_pad;   //need to figure out a way for each piece

        armor_attributes l_shoulder_pad;       //of armor to have attributes, such as

        armor_attributes r_glove;              //durability, cost, protection factor,

        armor_attributes l_glove;                  //weight, etc. Structure within a

        armor_attributes breast_piece;                 //structure, perhaps?

        armor_attributes abdominal_piece;
        armor_attributes belt;
        armor_attributes r_thigh_guard;
        armor_attributes l_thigh_guard;
        armor_attributes r_shin_plate;
        armor_attributes l_shin_plate;
        armor_attributes r_boot;
        armor_attributes l_boot;
};

void init_player_armor() {        //set armor ratings to begin the game with.

        armor player;   //instance of struct armor


        player.helmet.price=10;
        player.helmet.durability=50;
        player.helmet.weight=5;
        player.helmet.protection=2;
}

void display_armor() {                //must be an easier way here too..

        armor player;
        cout << "Helmet rating: " << player.helmet.protection << endl;
        cout << "Neck guard rating: " << player.neck_guard.protection << endl;
        getch();
}

void display_main_menu()         //the main main menu

{
        clrscr();
        cout << "Adventure Land!" << endl;
        cout << "[N]ew" << endl;
        cout << " ";
}

void do_stuff()
{
        display_main_menu();
        init_player_armor();
        display_armor();
}

void main()
{
do_stuff();
}  
Here are my questions: 1. I haven''t yet learned so much about scope, so here goes: I understand that variables declared in a statement block have scope in that block and blocks within that block. My question about scop is this: As you can see in my program, pretty much the way it is is that I have one block after another, and none of them are nested. So I was thinking that perhaps if that''s the case, variables declared in statement blocks above other statement blocks have scope within the others? Am I right in assuming this? 2. My other question is this: considering all the data members in my structures are the same type, is there a fast way to initialize all the data members? I tried doing this, but my compiler told me that it couldn''t convert type ''int'' to type ''armor''. 3. I completely stumbled onto the syntax shown above in which I referenced to player.helmet.price, etc. and I was wondering if this is good practice or not.. I can''t find anything about it in any of my texts.. I was also wondering if there''s any sort of limit to the number of structs within structs. 4. If I''m doing anything poorly, or there''s a way to make this easier and quicker, PLEASE LET ME KNOW! Sorry I''m such a newbie. Thanks a ton!, ~Kevinator

Share this post


Link to post
Share on other sites
Colin Jeanne    1114
1.

void init_player_armor()
{
//set armor ratings to begin the game with.
armor player; //instance of struct armor
player.helmet.price=10;
player.helmet.durability=50;
player.helmet.weight=5;
player.helmet.protection=2;
}

player has scope for this function and this function only. When this function returns player is automatically destroyed. To make sure that player is not destroyed when the function returns you could pass a reference to an armor object to the function like this:

void init_player_armor(armor &player)

the rest of your function would then look pretty much the same:

player.helmet.price=10;
player.helmet.durability=50;
player.helmet.weight=5;
player.helmet.protection=2;

You could initially create the armor object that you pass to the functions that modify it in main().



I will not make a list of links... I will not make a list of links... I will not make a list of links...
Invader''s Realm

Share this post


Link to post
Share on other sites
Kevinator    229
When I change my original code to this:
void init_player_armor(armor &player) 


What, then, belongs in
init_player_armor() 
as an argument when called in the function
do_stuff() 
? Nothing I try works..

Thanks

Share this post


Link to post
Share on other sites
Colin Jeanne    1114
quote:
Original post by Kevinator
When I change my original code to this:
void init_player_armor(armor &player)  


What, then, belongs in
init_player_armor()  
as an argument when called in the function
do_stuff()  
? Nothing I try works..

Thanks


If you made an armor object in main() and then used do_stuff() to initialize the struct by calling init_player_armor(), etc, you would need to also change

void do_stuff()

to

void do_stuff(armor &player)

so that you can pass the instance you make in main() to do_stuff() which in turn passes that to the other functions init_player_armor() and display_armor() (whose definition you also would need to change to accept a reference to an armor object).

What this is doing is giving ownership of player to main(), meaning main() is in charge of initializing, using, and destroying the player object. It''s easier if main() doesn''t initialize, use, and destroy the object itself but rather if it delegates those responsibilities to other functions. This makes main a smaller, cleaner function and makes your code easier to debug in the long run because you can track a bug down to a specific function by following the path of the object if it is giving you trouble. Finally this gives your program a clearer structure because main() is sole the owner of player instead of player having apparently no owner - and thus nothing to claim responsibility for player''s destruction and cleaning up - if player had been created in and returned from a function.

This function would make an object who''s owner is difficult to determine:

char *MakeSomeString()
{
char *something;

something = new char[25];

return something;
}

something is created in MakeSomeString() but it is not destroyed in MakeSomeString(). Why is this a bad thing? It leaves room for memory leaks that are more difficult to track down since you are relying on the programmer (you) to have to delete the memory allocated in MakeSomeString() in some other function.



I will not make a list of links... I will not make a list of links... I will not make a list of links...
Invader''s Realm

Share this post


Link to post
Share on other sites
Jason Zelos    211

define:
void init_player_armour(armour &player){//blah}

call:
init_player_armour(player);

You are passing a reference to the var player. As Invader X said, watch your scope for player though (or define it as global).A reference to it has to pass though all the functions between main (where declared) and init_player_armour (where used).

,Jay

Share this post


Link to post
Share on other sites