Initializer lists?

hello everybody
i'm trying to create a simple sfml game, but got stuck in some class' concepts:
this is a simplified code, in which i have 3 classes: Character, Player & CharHandler.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Character{
    protected:
    std::string name; //character's name
    sf::Vector2f pos; //character's position
    sf::Sprite char_sprite; //character's sprite

    public:
    Character();
    ~Character();
};


class Player : public Character{
    public:
    Player(){
        name = "Stauricus";
    }
    ~Player();
};


class CharHandler{
    std::vector <sf::Texture> char_textures; //vector for all character's textures
    Player player;

    public:
    CharHandler(){
        char_textures.resize(1);
        char_textures[0].loadFromFile("images/test.png");
    }
    ~CharHandler();
};


this code compiles fine; what i want is to change the Character constructor to this:
1
2
3
Character::Character(sf::Texture texture){
    char_sprite.setTexture(texture);
}


but it then return me an error in the Player constructor (line 15), saying
no matching function for call to ‘Character::Character()’


aditional info:
-there's only one CharHandler object
-sf::Sprite needs a sf::Texture to work. the number of sf::Texture should be kept at a minimum.


and my questions are:
1- how to make this constructor work? i read about "initialization lists", but wasn't able to solve it.
2- in line 2, if i change "protected" for "private", i get an error at line 16, saying that 'name is private'. is that expected, since Player is derived from Character?

thanks in advance!
In reverse order:

2 - is that expected

yes, it's expected

private = accessible by only that class
protected = accessible by that class and those derived from it
public = accessible by everything

see the table in the "Inheritance between classes" section on this page:

Friendship and inheritance
http://www.cplusplus.com/doc/tutorial/inheritance/

1- how to make this constructor work?

I'm not sure it's going to work without some adjustments to CharHandler.

Your CharHandler class currently has a Player member. If you add a texture parameter to the Character constructor, which Player is derived from, then you'll need to have the texture available when you construct the Player.

But I can see CharHandler loading a texture in its constructor body, which is run after its members (including the player) are constructed.

You will have to either (a) set the texture after construction or (b) change the Player member to a Player* (or std::unique_ptr<>) member and construct it dynamically after loading the required texture.

And you might consider passing the name to the Character constructor.

Andy

Using std::unique_ptr and initializer list

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Character{
    private:
    std::string name; //character's name
    sf::Vector2f pos; //character's position
    sf::Sprite char_sprite; //character's sprite

    public: // note it's const sf::Texture& not sf::Texture
    Character(const std::string& charname, const sf::Texture& texture);
    ~Character();
};

// using Sprite (const Texture &texture) form of sprite constructor
Character::Character(const std::string& charname, const sf::Texture& texture)
: name(charname), char_sprite(texture){
}

// Player constructor now passing parameters onto Character constructor
class Player : public Character{
    public:
    Player(const std::string& charname, const sf::Texture& texture)
    : Character(charname, texture) {
    }
    ~Player();
};

class CharHandler{
    std::vector <sf::Texture> char_textures; //vector for all character's textures
    std::unique_ptr<Player> player;

    public:
    CharHandler() {
        char_textures.resize(1);
        char_textures[0].loadFromFile("images/test.png");

        std::unique_ptr<Player> newPlayer(new Player("Stauricus", char_textures[0]));
        player = std::move(newPlayer);
    }
    ~CharHandler();
};


Last edited on
its constructor body, which is run after its members (including the player) are constructed.

oh, i didn't knew about that. i tought the constructor was the very first thing to be executed when the class was created. makes sense. thanks for your help :)
i tought the constructor was the very first thing to be executed when the class was created.

It is, but not necessarily the constructor body.

The order things happen during construction is:

1. base class constructors - left to right as they appear at beginning of the class declaration
2. members - in the order they are declared in the class, not the order they appear in the initializer list
3. then the body of the constructor

Andy

PS if you have virtual base classes, they get excuted before the non-virtual ones.
Last edited on
oh, i understand now. thanks again :)
Topic archived. No new replies allowed.