user1725794
user1725794

Reputation: 267

Issue regarding Initialization Lists C++

For example, say I have the following code;

class Foo
{
    public:
    Foo(int x) : _foo(x)
    {

    }

    private:
    int _foo;

    protected:
    std::string _bar;
};

class Bar : public Foo
{
    public:
    Bar() : Foo(10), _temp("something"), _bar("something_else")
    { 

    }
    private:
    std::string _temp;
};

int main()
{
    Bar stool;
}

The code doesn't run because _bar is of the class Foo and it doesn't appear to know it exists, so is this not how you would go about doing it? Or would you just have _bar in Foo's constructor? This would work but what if _bar doesn't always have to be assigned something?

Edit: Below is the real code I was using;

Entity::Entity(GameState *state, bool collidable) 
    :_isLoaded(false), _state(state), alive(true), collidable(collidable),               name(entityDetault)

{

}

Entity::Entity(GameState *state, bool collidable, entityName _name)
    :_isLoaded(false), _state(state), alive(true), collidable(collidable), name(_name)
{

}

and then the child class would use this constructor;

Player::Player(GameState *state) 
: Entity(state,true,entityName::entityPlayer), health(100),bulletSpeed(600),_colour(sf::Color(128,255,86,255))

Does this all look correct now? Slightly better than doing it all in the constructor body.

Upvotes: 2

Views: 91

Answers (4)

taocp
taocp

Reputation: 23624

You may put _bar in Foo's constructor's initialization list. If _bar does not always need be to assigned something, you can use default value.

class Foo
{
public:
   Foo(int x):_foo(x)
   {
   }
protected:
   Foo(int x, string s) : _foo(x),_bar(s)
   {

   }

private:
   int _foo;

protected:
   std::string _bar;
};

class Bar : public Foo
{
public:
   Bar() : Foo(10,"something else"), _temp("something")
   { 

   }
private:
  std::string _temp;
};

Upvotes: 1

Daniel Frey
Daniel Frey

Reputation: 56863

You could either move it from the initializer list to the body (if it is not const):

Bar() : Foo(10), _temp("something")
{
    _bar = "something_else";
}

or provide a second (maybe protected) contructor for Foo:

class Foo
{
public:
    Foo(int x) : _foo(x)
    {

    }

protected:
    Foo(int x,std::string s) : _foo(x), _bar(s)
    {
    }

private:
    int _foo;

protected:
    std::string _bar;
};

class Bar : public Foo
{
public:
    Bar() : Foo(10,"something_else"), _temp("something")
    { 

    }

private:
    std::string _temp;
};

Upvotes: 2

SomeWittyUsername
SomeWittyUsername

Reputation: 18338

You need to initialize the base class before you can access it. If you want to initialize member variable in the base class, you have to do it via call to base class constructor in which will initialize it's members.

Upvotes: 1

The member initialiser list in a constructor of class C can only initialise:

  • direct base classes of C
  • direct members of C
  • virtual base classes of C (doesn't come up too often)

The only way to initalise a member of a base class is through a constructor of the base class. Or just forego initialisation and then do an assignment in the body of C's constructor. The latter cannot be used for const members or references, though, and in general does not do the same thing as just initialisation.

Upvotes: 5

Related Questions