Home > Enterprise >  Different behaviour list initialization when specifying constructor
Different behaviour list initialization when specifying constructor

Time:01-04

I have code like this for example :

class A {
public:
    int x;

    A() {
        std::cout << "Constructor Called !" << std::endl;
    }
    A(int y):x(y) {
        std::cout << "Constructor Param Called !" << std::endl;
    }

    A(const A& copy) {
        std::cout << "Copy Constructor Called !" << std::endl;
    }
}

class B {
public:
    A value;
    //B(const A& val) : value(val){}
}

int main(){
    B b { A(22)};
}

If i comment out the B constructor the output is just "Constructor Param Called", but if i uncomment B constructor the output would be "Constructor Param Called" & "Copy Constructor Called". My questions :

  1. Why is the output different if i commented out the constructor ? (I've read about aggregate class & aggregate initialization, is this it ?)
  2. What's the difference between aggregate initialization & direct initialization ?

CodePudding user response:

When you remove the user-provided constructor for B, B becomes an aggregate. So aggregate-initialization is performed where each element of the class is copy-initialized from the elements of the initializer list. Since A(22) is a prvalue of the same class as B's element, copy-elision takes place where the value is stored directly into the object without any calls to the copy-constructor. This is new as of C 17.

When you declare the constructor for B, it is no longer an aggregate, so constructors are considered when you're doing an initialization.

Direct-intialization just means there is no = sign when you're initializing an object. Aggregate-initialization is what takes place when you're initializing an aggregate, and you can take a look at the definition on cppreference for that.

  • Related