Inheritence, Constructors, and Arrays oh my!

Started by
24 comments, last by psiko_scweek 17 years, 7 months ago
Ok, ignore the crappy title. anyways, Ive run into a small problem and I have no idea as to what I did wrong (probably a lot though) Im trying to learn the fundamentals of SDL and C++ so im learning by trial and error. eitherway, here is my issue: I have a constructors for my objects
[SOURCE]
/////////// INITIALIZE THE OBJECT STRUCTURES ///////////
class Object 
{ 
protected: 
int x, y; 
int graphicwidth;
int graphicheight;
int height, width;
int solid;
SDL_Surface *graphic;

public: 
Object(int tempx, int tempy, SDL_Surface *tempgraphic) : x(tempx), y(tempy), graphic(tempgraphic)
{}
~Object();
void step(); 
void draw(); 
void setGraphicHeight(int tempHeigt);
void setGraphicWidth(int tempWidth);
int getGraphicHeight();
int getGraphicWidth();
void setSolid(int tempSolid);
void setX(int tempX);
void setY(int tempY);
int getX();
int getY();
int direction;
void setGraphic(SDL_Surface *graphic);
};
[/SOURCE]
and it works great for the object class. I have two subclasses MasterControl and PlayerBlocks. Now here is where my problems come in, doing research i found that I had to set up the contructors for the subclasses too, not a problem. But here is where my problem comes in, I use an array for my PlayerBlocks objects
[SOURCE]
/////////// CREATE THE OBJECTS /////////// 
PlayerBlocks VerticalBlue[NumberOfBlocks];
MasterControl Master(0,0,NULL);
Object Background(0,0,gfx_background);
Object Titleimage(0,0,gfx_titleimage);
Object Bottomimage(0,233,gfx_bottomimage);
Object TopWall(16,120,gfx_topwall);
Object BottomWall((SCR_H)-16, 120, gfx_bottomwall);
Object LeftWall(120,10, gfx_leftwall);
Object RightWallTop(363, 16, gfx_rightwalltop);
Object RightWallBottom(363,(SCR_H)-(13+RightWallBottom.getGraphicHeight()), gfx_rightwallbottom);
[/SOURCE]
but whenever I try to compile I get an error message stating: "no matching call to PlayerBlocks::PlayerBlocks()" So I tried to change the PlayerBlocks to:
[SOURCE]
/////////// CREATE THE OBJECTS /////////// 
PlayerBlocks VerticalBlue[NumberOfBlocks](0,0,NULL);
[/SOURCE]
and it still has problems error message: "bad array initializer" any ideas on what i did wrong?! thanks psiko
Advertisement
You must provide a default constructor for your class to be able to create an array of it.
Objects in an array can only be constructed via default constructor.
There's no C++ syntax allowing you to use other constructors, pass any parameters, etc.

Possibilities:

1. Provide (and use) default constructor and initialize the objects by hand with some function. You're doing something similar already, so it should be of no problem.

2. Use array of pointers:
PlayerBlocks* VerticalBlue[NumberOfBlocks];
for (int i=0; i<NumberOfBlocks; ++i)
VerticalBlue = new PlayerBlocks(params);
...
for (int i=0; i<NumberOfBlocks; ++i)
delete VerticalBlue;


You could use inheritance at this point, and instead write:
Object* VerticalBlue[NumberOfBlocks];

3. Use in-place construction. This is an advanced topic, so I discourage this.

-------

IMO, nr.2 should be your choice here.
Quote:Original post by deffer
Objects in an array can only be constructed via default constructor.
There's no C++ syntax allowing you to use other constructors, pass any parameters, etc.


Not 100% true.

object array[] = { object(1,2,3) , object(4,5,6) };

In this case, both elements of array are copy constructed from temporaries which in turn were constructed with (1,2,3) and (4,5,6) respectively.

psiko_scweek: It looks to me like the best solution here is a default constructor for Object, though.
ok, the default constructors work fine and compile without errors.

I noticed though that the graphics or other objects in my game dont show...

if i use the default contructor i have to eliminate this line?!

Object(int tempx, int tempy, SDL_Surface *tempgraphic)

and instead use

Object()

hmmm....is there anything else i may have missed?
unless you are a fan of hardcoding the objects in your game look into std::vector, and the other standard template libraries. std::vector is a dynamic array basically.

http://gpwiki.org/index.php/C_plus_plus:Modern_C_plus_plus:Vectors

one of my friends wrote that up. Should help you in understanding it.

to understand the basic idea here.

std::vector<object*> objectArray;
for(...){ create the objects
objectArray.push_back(new object(0,0,NULL));
}
you can access them with iterators or just like a regular array
objectArray[0]->setX(5);

just remember to delete objects on the heap if you need to :)
while(!objectArray.empty()){
delete objectArray[objectArray.size()-1];
objectArray.pop_back();
}
something along the lines of that...
When you get into polymorphism you will be really excited.
You can avoid the need for a default constructor, as std::vector does, by using placement new.
Yoni Levy.
Quote:Original post by psiko_scweek
if i use the default contructor i have to eliminate this line?!


No, you can have multiple constructors.

Quote:You can avoid the need for a default constructor, as std::vector does, by using placement new.


E.g. "in place construction" as deffer already mentioned and provided rationale against - although I'd argue it more along the point of "...why? It seems obvious we're constructing to a default - 'uninitialized' state - why not just use the default constructor, since that's what it's for?"
Quote:Original post by MaulingMonkey
Quote:You can avoid the need for a default constructor, as std::vector does, by using placement new.


E.g. "in place construction" as deffer already mentioned and provided rationale against - although I'd argue it more along the point of "...why? It seems obvious we're constructing to a default - 'uninitialized' state - why not just use the default constructor, since that's what it's for?"


From my point of view, an object should never be in an "unitialized state" after construction. That's not the purpose of the constructor, its purpose is to construct the object, and bring it to an initialized state. Adding a default constructor "just for things to work", isn't reasonable.

In place construction seems very reasonable to me, the object doesn't exist before it's constructed, its just raw memory we're handling with, and once construction has taken place, the object is initialized and ready to be worked with.

Besides, it shouldn't be an "advanced topic" if you use an implementation such as std::vector.
Yoni Levy.
Quote:Original post by GPX
Besides, it shouldn't be an "advanced topic" if you use an implementation such as std::vector.


If I get you right, you're saying that "if std::vector is using it, anybody can use it".
IMO, implementing (and doing it right) something as complex as std::vector is an advanced topic.

This topic is closed to new replies.

Advertisement