Sign in to follow this  

private array data in class

This topic is 4108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm writing (although trying to write might be more accurate) a classic asteroids clone. I have a number of classes based on a model class (asteroid, ufo, missile, etc.). Currently, the point data for each class instance is effectively used and declared globally, like so: -- in main.cpp --
  ship mainShip;

  point3d shipPoints[] = { point3d( 8.0, 0.0, 0.0),
                           point3d(-8.0,-6.0, 0.0),
                           point3d(-1.0, 0.0, 0.0),
                           point3d(-1.0, 0.0, 0.0),
                           point3d(-8.0, 6.0, 0.0),
  };
  int shipPoly[] = {0,1,2,3,4};

  int main() {

    ...

    // create ship mesh
    mesh* shipMesh = new mesh;
    shipMesh->AddPoints(shipPoints, sizeof(shipPoints)/sizeof(shipPoints[0]));
    shipMesh->AddPoly(shipPoly, sizeof(shipPoly)/sizeof(int));

    mainShip.setMesh(shipMesh);

    ...

    return 1;
  };
Which is working fine. After much deliberation I've decided that the point data should be the responsibility of the class and should not be visible globally. Leading to this: -- in ship.cpp --
  point3d shipPoints[] = { point3d( 8.0, 0.0, 0.0),
                           point3d(-8.0,-6.0, 0.0),
                           point3d(-1.0, 0.0, 0.0),
                           point3d(-1.0, 0.0, 0.0),
                           point3d(-8.0, 6.0, 0.0),
  };
  int shipPoly[] = {0,1,2,3,4};

  ship::ship() {

    ...

    // create ship mesh
    mesh* shipMesh = new mesh;
    shipMesh->AddPoints(shipPoints, sizeof(shipPoints)/sizeof(shipPoints[0]));
    shipMesh->AddPoly(shipPoly, sizeof(shipPoly)/sizeof(int));

    this->setMesh(shipMesh);

    ...

  };
Apart from the questionability of hard coding values into a class, this doesn't work as I hoped. shipPoints has 5 elements but they're all (0, 0, 0), although shipPoly is (0,1,2,3,4). Is there a way to get this working? I did get this working a few days ago, but promptly changed my mind and undid all the changes. Now I can't remember how I did it and my current attempts are proving unsuccessful... Basically, I want the default array data to be visible in ship.cpp only. Suggestions welcome (to say the least). Thanks in advance. Carl Bateman

Share this post


Link to post
Share on other sites
This is a problem of order of initialization of global variables.
You've got (at least) two global variables:

ship mainShip;
point3d shipPoints[];

They are initialized (constructed) before the main() launches and destroyed after main() returns. But in which order? There are several rules for this, mainly:
1. If the objects are in same translation unit (read: in same .cpp file), then they are initialized in the same order they are declared.
2. If the objects are in different translation units, the order is undefined - depending on how the linker links the compiled modules (.o, or .obj files) together.

Long story short, mainShip's constructor launches before the shipPoints array gets initialized. What you could do? Several choices:
1. Move ship mainShip from globals! Make it a local variable in main(). If you abolutely must have global access to your ship, make ship *pMainShip global pointer and in main() initialize it with
ship mainShip;
pMainShip = &mainShip


2. Move point3d shipPoints[] and int shipPoly[] into ship::ship() constructor.
ship::ship()
{
static const point3d shipPoints[] =
{
point3d( 8.0, 0.0, 0.0),
point3d(-8.0,-6.0, 0.0),
point3d(-1.0, 0.0, 0.0),
point3d(-1.0, 0.0, 0.0),
point3d(-8.0, 6.0, 0.0),
};
static const int shipPoly[] = {0,1,2,3,4};

// ...
};

Then you'll be sure that your data will be there when you need it. static keyword makes sure that the data will be initialized only once.
The difference between your current code and this is that the shipPoints and shipPoly will be initialized exactly on ship::ship() first run.

Share this post


Link to post
Share on other sites
I don't see anything wrong with the first version of the code. Points/Polys are just data that are read into Mesh. The fact that they're global here is pretty much irrelevant; it would be harmful if the Mesh class actually used those global arrays directly, but you don't do that: you properly pass it as parameters through AddPoints/AddPoly. The design is okay, the data could be anything from global,local or data loaded from a file(which is actually what you should be doing). Embedding the graphic data into the Ship class is not a good idea, IMO it's far worse than the first version. Since you already have a Mesh class, Ship does not need to know anything at all about visual representation.

Share this post


Link to post
Share on other sites
Thanks for the feedback, guys.

It occurred to me on the train ride back home this evening that I'm actually violating my own design intentions (what there is of them). I really want to minimise the memory used by geometry definitions by having them in a seperate collection, not in the classes. Do'h!!!

I'd still like to be able to do what I was trying earlier, that is, set up some default model geometry inside the class without exposing it.

I believe that deffer is on the right track with regard to the initialisation order (judicious break point placement that doesn't break when it "should" and a second model initalisation with new that works certainly support his point of view). It was probably dumb luck that it worked before.

Is there anyway I can force the order of unit processing?

Share this post


Link to post
Share on other sites

This topic is 4108 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this