Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I'm confused about this C++ constructor

I tried searching for an answer, but not sure exactly the best terms to use to describe this...

I am reading a book on SFML programming, and one of the examples has me confused with the usage of the constructor.

Lets say we have class A and class B. Class A has a member variable of type B (memberB). The constructor for A looks like:

A::A() : OtherMemberType(with, params), memberB()
{...}

Given that memberB is being initialized with the default constructor in the initialization list, what is the purpose of explicitly listing it in the list? Wouldn't the same effect be had without including it in the list?

Thanks

EDIT: Thanks for the answers. I have now learned the (basic) difference of value-initialization vs. default-initialization.

For more context, since the idea of "class B may be broken was brought up", here is the code example from the text SFML Game Development:

class Game
{
    public:Game();
        void             run();

    private:
        void             processEvents();
        void             update();
        void             render();

    private:
        sf::RenderWindow mWindow;
        sf::CircleShape  mPlayer;
};

Game::Game()
: mWindow(sf::VideoMode(640, 480), "SFML Application")
, mPlayer()
{
    mPlayer.setRadius(40.f);
    mPlayer.setPosition(100.f, 100.f);
    mPlayer.setFillColor(sf::Color::Cyan);
}

So with that context, does anyone know some of the specifics of SFML? Is sf::CircleShape "broken", or is this a redundant call to the default constructor?

Adam

like image 529
Adam Rosen Avatar asked Jan 24 '15 16:01

Adam Rosen


2 Answers

Initializing the member in the initializer list value-initializes it. Omitting it from the list default-initializes it,

If B is a non-aggregate and has a default constructor, there is no difference.

If B is an aggregate, then there may be a difference. default-initializing it means if it contains built-ins these may not get initialized. value-initializing it would eventually have the effect of zero-initializing its members.

This is an example where the semantics of the initialization would be different:

struct B
{
  int i, j, k;
};

struct A
{
  A() : b() {} // value-initializes b: b.i, b.j, b.k zero initialized

  B b;
};

struct AA
{
  AA() {} // default-initializes b: b.i, b.j, b.k have no initialization

  B b;
};
like image 132
juanchopanza Avatar answered Sep 20 '22 13:09

juanchopanza


By including it in the initialiser list, the member is value-initialised. If it weren't, it would be default-initialised. Whether there's a difference depends on the type.

If it's a class type with a declared default constructor, then there's no difference: that constructor will be used in either case.

Otherwise, value-initialisation will zero-initialise primitive types (and primitive members of class types), while in some circumstances default-initialisation will leave them uninitialised, with an indeterminate value.

UPDATE: In your specific case, the class does have a default constructor, so the explicit initialisation is redundant. But redundancy isn't necessarily a bad thing - it indicates that it's being deliberately value-initialised, not just forgotten about.

like image 28
Mike Seymour Avatar answered Sep 21 '22 13:09

Mike Seymour