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

Discussion in 'C++' started by Alvin, Dec 1, 2006.

  1. Alvin

    Alvin Guest

    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
     
    Alvin, Dec 1, 2006
    #1
    1. Advertising

  2. Alvin wrote:
    > [..]
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Dec 1, 2006
    #2
    1. Advertising

  3. Alvin

    Alvin Guest

    Victor Bazarov wrote:
    > Alvin wrote:
    > > [..]
    > > 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
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


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

    Thanks,
    Alvin
     
    Alvin, Dec 1, 2006
    #3
  4. Alvin

    David Harmon Guest

    On 1 Dec 2006 11:16:53 -0800 in comp.lang.c++, "Alvin"
    <> wrote,
    >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.
     
    David Harmon, Dec 1, 2006
    #4
  5. Alvin

    Jim Langston Guest

    "David Harmon" <> wrote in message
    news:...
    > On 1 Dec 2006 11:16:53 -0800 in comp.lang.c++, "Alvin"
    > <> wrote,
    >>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.


    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.
     
    Jim Langston, Dec 2, 2006
    #5
  6. Alvin

    David Harmon Guest

    On Fri, 1 Dec 2006 22:37:47 -0800 in comp.lang.c++, "Jim Langston"
    <> wrote,
    >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;
     
    David Harmon, Dec 2, 2006
    #6
  7. Alvin

    BobR Guest

    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<std::vector<block> > grid; // note space between '> >'

    > 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))){}

    --
    Bob R
    POVrookie
     
    BobR, Dec 2, 2006
    #7
  8. Alvin

    Old Wolf Guest

    BobR wrote:
    > Alvin wrote:
    > > 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).
     
    Old Wolf, Dec 3, 2006
    #8
  9. Alvin

    BobR Guest

    Old Wolf wrote in message
    <>...
    >BobR wrote:
    >> Alvin wrote:
    >> > 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.

    --
    Bob R
    POVrookie
     
    BobR, Dec 3, 2006
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Madni
    Replies:
    1
    Views:
    406
  2. morrell
    Replies:
    1
    Views:
    975
    roy axenov
    Oct 10, 2006
  3. =?ISO-8859-1?Q?Martin_J=F8rgensen?=
    Replies:
    5
    Views:
    1,315
    =?ISO-8859-1?Q?Martin_J=F8rgensen?=
    May 6, 2006
  4. Replies:
    3
    Views:
    381
  5. Old Wolf
    Replies:
    0
    Views:
    477
    Old Wolf
    Jan 28, 2009
Loading...

Share This Page