Arrays of Objects with Constructors

Started by
6 comments, last by Fruny 19 years, 2 months ago
Hi guys, I'm busy writing a small game and i'm using a set of classes to define obstacles in C++. The game is called 'Jobber' btw I've got a class JobberObstacle which has a constructor which demands a struct JobberObstacleData. Logical? I thought so. Thing is, I've got my another class (very important one) JobberMap which has to store lots of JobberObstacles. Hence: class JobberMap { public: // blah protected: JobberObstacle obstacle[50] = { blank }; }; Now of course the compiler (in this case VC++6.0) of course is complaining about that because you can't make assignments in a class definition. Any ideas? The actual errors are: p:\jobber\appstruct\jmap.h(35) : error C2059: syntax error : '{' p:\jobber\appstruct\jmap.h(35) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body and blank is a global JobberObstacleData which i'm sure is ok. Hope this is the right forum for this problem, seems quite advanced to me but i'm sure its an amateur problem to all you elite programmers. Thanks for any help. oLE
Advertisement
What i do, typically in this kinda situation is have a class look like this:

class jobber{public:  jobber()  {    objectInitialised = false;  };  jobber(jobberdata& data)  {    objectInitialised = false;    Assign(data);  }  ~jobber(){};  void Assign(jobberdata& data)  {    if (!objectInitialised)    {      // do stuff      objectInitialised = true;    }  }}


This way the object can only be initialised once, but is initialised false as default.

ace
for (int i = 0; i < 50; i++){  obstacle = *(new JobberObstacle());}


or change JobberObstacle obstacle[50];

to

JobberObstacle* obstacle[50];

and use

for (int i = 0; i < 50; i++){  obstacle = new JobberObstacle();}


Note: Replace JobberObstacle() with which ever constructor for JobberObstacle that you want to use.
thanks for the help. I think i'll go for the for loop one and just do the constructing in that loop. I've never used all that DMA, new, delete stuff.

oLE
Ole_v2 - An array can only contain objects which have a default constructor, since that's how the array is initialized. Only POD-types (i.e. C-compatible types) can be initialized with array literals (as you were trying to do). Your only solution is to loop and assign to the array elements.

ace_lovegrove - Initialization lists. I'm not sure I'd enjoy peppering all my member functions with the necessary checks against objectInitialised ... well, I guess assertions are OK.

Dragoncar - Your first example leaks memory like there is no tomorrow!
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Ha ha! :D Fruny sets it straight.
Quote:An array can only contain objects which have a default constructor, since that's how the array is initialized. Only POD-types (i.e. C-compatible types) can be initialized with array literals (as you were trying to do). Your only solution is to loop and assign to the array elements.


I'm not so sure Fruny...I might not have remembered this correctly but i thought i heard that you can initalize the values of class members outside the class using the scope resolution operator rather than in the constructor. but i can't work out the syntax or find it documented in my travels.

Going back to my original example, here's how i think it should work.

class JobberMap {public:// blahprotected:JobberObstacle obstacle[50];};JobberObstacle JobberMap::obstacle[50] = { (param,param) }


but i just get:

Error C2073: 'protected: static class JobberObstacle * JobberMap::obstacle' : partially initialized array requires a default constructor

does anyone know that correct syntax it would be nice if i could avoid all the hassle the for loop of:

JobberMap::JobberMap() {const int obstacles = sizeof obstacle / sizeof obstacle[0];	for (int i=0; i<obstacles; i++) {		obstacle.Make(blank);	}

Edit - don't use for long lines, use .

[Edited by - Fruny on February 15, 2005 2:36:30 PM]
Quote:JobberObstacle JobberMap::obstacle[50] = { (param,param) }


That (param,param) is NOT a pair of parameters. Read up on operator,()

Quote:Error C2073: 'protected: static class JobberObstacle * JobberMap::obstacle' : partially initialized array requires a default constructor


static - A static member is just like a global variable. You can initialize those. Not non-static members.

partially initialized - You specified one of an array of fifty elements. The remaining elements are default-initialized. Or would be if you had a default-constructor.

Show the definition of the JobberObstacle type.

Quote:does anyone know that correct syntax it would be nice if i could avoid all the hassle the for loop


std::fill, std::fill_n, std::for_each or std::uninitialized_fill depending on how exactly you want to do things. The most efficient is probably uninitialized_fill, but it's also the most complex to use (it uses placement new).

Anything beyond that is, to the best of my knowledge, a compiler extension. I'll be happy to be proven wrong, though.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

This topic is closed to new replies.

Advertisement