c++c++11constructorstandards-compliance

Construction and initialization list : what the compiler do?


I have some questions about constructors in C++. For each question (from (1) to (4)) I would like to know if the behaviour is perfectly defined regarding to the standard.

A) The first one is about initialization of members :

class Class
{
    public:
        Class() 
        : _x(0)
        , _y(_x)
        , _z(_y) // <- (1) Can I initialize a member with other members ?
        {
            ;
        }

    protected:
        int _x;
        int _y;
        int _z;
};

B) What are the functions added to each class by the compiler ?

template<typename T> class Class
{
    public:
        template<typename T0>
        Class(const Class<T0>& other)
        {
            std::cout<<"My copy constructor"<<std::endl;
            _x = other._x;   
        }

        template<typename T0 = T>
        Class (const T0 var = 0)
        {
            std::cout<<"My normal constructor"<<std::endl;
            _x = var;
        }

    public:
        T _x;
};

// (2) Are 
// Class(const Class<T>& other) 
// AND 
// inline Class<T>& operator=(const Class<T>& other)
// the only functions automatically added by the compiler ?

As an example, if I call :

Class<int> a;
Class<int> b(a); // <- Will not write "My copy constructor"
Class<double> c(a); // <- Will write "My copy constructor"

(3) Is this behaviour perfectly normal according to the standard ?

(4) Do I have the guarantee that an empty constructor is not automatically added and that Class<int> x; will write "My normal constructor" ?


Solution

  • Can I initialize a member with other members ?

    Yes, as long as those other members have already been initialised; i.e. as long as their declarations come before the member being initialised.

    Are [the copy constructor] and [the copy-assignment operator] the only functions automatically added by the compiler ?

    It will also implicitly declare a destructor, which will destroy _x using its destructor.

    In C++11, a move constructor (Class(Class&&)) and move-assignment operator (Class& operator=(Class&&)) are also implicitly declared, unless you declare a copy or move constructor, or a copy or move assignment operator.

    Note that your constructor template is not a copy constructor, and the implicit one will be used instead:

    Class<T1> t1;
    Class<T1>(t1); // prints nothing
    Class<T2>(t1); // prints "My copy constructor" (which is a lie)
    

    Is this behaviour perfectly normal according to the standard ?

    Yes, see chapter 12.

    Do I have the guarantee that an empty constructor is not automatically added and that Class<int> x; will write "My normal constructor" ?

    Yes, a default constructor will only be implicitly declared if you don't declare any constructors at all.