g++ throws: error: no matching function for call to `block::block()'

A

Alvin

I'm making a very simple game in SDL, and I'm not asking for SDL help I
hope - this looks like something C++ related, so I'll ask here.

I have a class for a simple block, or tile, in the game, which can be
either on or off. I'm having trouble with the constructor though.
class block
{
private:
SDL_Surface *screen;
SDL_Surface *surface;
Uint32 selcol;
Uint32 offcol;
bool on;

public:
block(SDL_Surface *);
bool blit(int, int);
void enabled(bool);
} ;

/* ... */

block::block(SDL_Surface *mscreen)
{
screen = mscreen;
surface = SDL_CreateRGBSurface(screentype, blockw, blockh, bpp,
screen->format->Rmask, screen->format->Gmask,
screen->format->Bmask,
screen->format->Amask);

selcol = SDL_MapRGB(screen->format, selcolr, selcolg, selcolb);
offcol = SDL_MapRGB(screen->format, offcolr, offcolg, offcolb);

/* default is off */
on = false;
SDL_FillRect(surface, NULL, offcol);
}
I'm calling it from my `game' class:
class game
{
private:
SDL_Surface *screen;
Uint32 bgcol;
block grid[w][h];
bool blitblock(int, int);

public:
game();

} ;
I don't think details matter too much, but with my game constructor,
which follows:
game::game()
{
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("couldn't initialise SDL: %s\n", SDL_GetError());
exit(1);
}

screen = SDL_SetVideoMode(screenw, screenh, bpp, screentype);

for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++)
grid[j] = block(screen);
}
I get the following error from g++:
g++ ./block.cpp ./game.cpp -c -lSDL -Wall
../game.cpp: In constructor `game::game()':
../game.cpp:4: error: no matching function for call to `block::block()'
../lgt.h:36: note: candidates are: block::block(const block&)
../lgt.h:45: note: block::block(SDL_Surface*)
I hope this is enough information - it's probably something really
stupid, too. The only thing I can think of is that I can't call the
constructor like I am for my block array.

Thanks,
Alvin
 
V

Victor Bazarov

Alvin said:
[..]
I get the following error from g++:
g++ ./block.cpp ./game.cpp -c -lSDL -Wall
./game.cpp: In constructor `game::game()':
./game.cpp:4: error: no matching function for call to `block::block()'
./lgt.h:36: note: candidates are: block::block(const block&)
./lgt.h:45: note: block::block(SDL_Surface*)
I hope this is enough information - it's probably something really
stupid, too. The only thing I can think of is that I can't call the
constructor like I am for my block array.

That's right. You have an array which has to be initialised. The
compiler has to use the default c-tor for 'block' to intialise the
array elements. But there is no defatul c-tor in 'block'. Add one.

The fact that you assign different values to 'grid' in the body of
the 'game::game' does not matter, the array has to be initialised
before entering the body.

V
 
A

Alvin

Victor said:
Alvin said:
[..]
I get the following error from g++:
g++ ./block.cpp ./game.cpp -c -lSDL -Wall
./game.cpp: In constructor `game::game()':
./game.cpp:4: error: no matching function for call to `block::block()'
./lgt.h:36: note: candidates are: block::block(const block&)
./lgt.h:45: note: block::block(SDL_Surface*)
I hope this is enough information - it's probably something really
stupid, too. The only thing I can think of is that I can't call the
constructor like I am for my block array.

That's right. You have an array which has to be initialised. The
compiler has to use the default c-tor for 'block' to intialise the
array elements. But there is no defatul c-tor in 'block'. Add one.

The fact that you assign different values to 'grid' in the body of
the 'game::game' does not matter, the array has to be initialised
before entering the body.

V

Thanks for the quick reply! How would I go about initialising the array
before it enters my game constructor, though?

Thanks,
Alvin
 
D

David Harmon

On 1 Dec 2006 11:16:53 -0800 in comp.lang.c++, "Alvin"
How would I go about initialising the array
before it enters my game constructor, though?

Exactly as Victor says, you must supply a default constructor for block
- one that can be called with no arguments.
 
J

Jim Langston

David Harmon said:
On 1 Dec 2006 11:16:53 -0800 in comp.lang.c++, "Alvin"


Exactly as Victor says, you must supply a default constructor for block
- one that can be called with no arguments.

In which case, since things need to be initialized to be used for your
class, you probably want to add an init() method which needs be called
before the class can be used. One possible thing to do is add a private
bool initialized_; and set it to false in the default constructor. Set it
to true in init and have calls check to see if it's initialized. Or set
your screen to NULL in the default constructor and test it, since you'll
initialize it in your init() method.
 
D

David Harmon

On Fri, 1 Dec 2006 22:37:47 -0800 in comp.lang.c++, "Jim Langston"
In which case, since things need to be initialized to be used for your
class, you probably want to add an init() method which needs be called
before the class can be used.

Alvin is currently setting up the array by copying with:

:: screen = SDL_SetVideoMode(screenw, screenh, bpp, screentype);
::
:: for(int i = 0; i < w; i++)
:: for(int j = 0; j < h; j++)
:: grid[j] = block(screen);

which is just as good as an init() method, in my opinion. Do you see an
advantage to init()? It could probably be micro-optimized a little
with:

screen = SDL_SetVideoMode(screenw, screenh, bpp, screentype);
block initblock(screen);
for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++)
grid[j] = initblock;
 
B

BobR

Alvin wrote in message
I'm making a very simple game in SDL, and I'm not asking for SDL help I
hope - this looks like something C++ related, so I'll ask here.
I have a class for a simple block, or tile, in the game, which can be
either on or off. I'm having trouble with the constructor though.

class block{
public:
block(SDL_Surface *);
} ;

I'm calling it from my `game' class:
class game{
private:
SDL_Surface *screen;
Uint32 bgcol;
block grid[w][h];

Suggestion:

std::vector said:
bool blitblock(int, int);
public:
game();
} ;

I don't think details matter too much, but with my game constructor,
which follows:
// >game::game()

game::game() : grid( w, h ) // note the colon
{
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("couldn't initialise SDL: %s\n", SDL_GetError());
exit(1);
}

screen = SDL_SetVideoMode(screenw, screenh, bpp, screentype);

for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++)
grid[j] = block(screen);


That will still work, or for better 'range safety':

for( size_t i( 0 ); i < grid.size(); ++i)
for( size_t j( 0 ); j < grid.at( i ).size(); ++j)
grid.at( i ).at( j ) = block( screen );
If you could somehow pass a 'screen' to your 'game' constructor, you could do
the whole initialization in the init list.

game::game( block screen ) : grid( w, std::vector<block>(h, block(screen))){}
 
O

Old Wolf

BobR said:
Alvin said:
block grid[w][h];

Note, 'w' and 'h' look like abbreviations for 'width' and 'height', but
this array has 'w' rows and 'h' columns.
Suggestion:

std::vector<std::vector<block> > grid; // note space between '> >'
game::game() : grid( w, h ) // note the colon

Of course, the OP code doesn't work unless w and h are constants.
So it does need modification. If you are going to go with a vector
of vectors (I wouldn't personally), then you might as well solve his
other problem at the same time, and stick with:

game::game(): grid(w) { ...

so that 'block' does not need to have a default constructor.

Then you can insert items into the vector that are already
constructed, rather than creating it full of empty ones and
then assigning them other values.
for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++)
grid[j] = block(screen);


That will still work, or for better 'range safety':

for( size_t i( 0 ); i < grid.size(); ++i)
for( size_t j( 0 ); j < grid.at( i ).size(); ++j)
grid.at( i ).at( j ) = block( screen );


If you're iterating from 0 to size, then you will always
be in range, so there's no need to bother with the 'at'.

Further, if you follow my above suggestion, namely
that grid be initialized to have 'w' empty rows, then
this line will initialize it:

std::fill( grid.begin(), grid.end(), std::vector<block>(h, screen)
);

If you could somehow pass a 'screen' to your 'game' constructor, you could do
the whole initialization in the init list.

game::game( block screen ) : grid( w, std::vector<block>(h, block(screen))){}

Agree, but 'screen' is the result of a function that's being called
in the constructor, so that would be a bit awkward (But not impossible).
 
B

BobR

Old Wolf wrote in message
BobR said:
Alvin said:
block grid[w][h];

Note, 'w' and 'h' look like abbreviations for 'width' and 'height', but
this array has 'w' rows and 'h' columns.

You know that, and I know that. But if:

vector<vector<block> > V2d( h, w );

....and OP did:

V2d[w][h] = something;

Oops (assuming w != h).
So, I left it 'w, h'.
Suggestion:
std::vector<std::vector<block> > grid; // note space between '> >'
game::game() : grid( w, h ) // note the colon
for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++)
grid[j] = block(screen);


That will still work, or for better 'range safety':

for( size_t i( 0 ); i < grid.size(); ++i)
for( size_t j( 0 ); j < grid.at( i ).size(); ++j)
grid.at( i ).at( j ) = block( screen );


If you're iterating from 0 to size, then you will always
be in range, so there's no need to bother with the 'at'.


You are looking at '.at()', I was looking at:

w vs. grid.size()
h vs. grid.at(i).size()

That's the "better 'range safety' " I was thinking about.
( assume there is no 'insert'/'erase' inside loop).

I left the '.at()'s in there to show an alt. usage.
I not only agree with you, but, usually point that out myself.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top