构造和初始化列表:编译器做什么?

时间:2012-11-14 03:59:46

标签: c++ compiler-construction constructor c++11 standards-compliance

我对C ++中的构造函数有一些疑问。对于每个问题(从(1)到(4)),我想知道对于标准是否完全定义了行为。

A)第一个是关于成员的初始化:

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)编译器为每个类添加了哪些函数?

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 ?

例如,如果我打电话:

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

(3)根据标准,这种行为完全正常吗?

(4)我是否保证不会自动添加空构造函数并且Class<int> x;会写"My normal constructor"

1 个答案:

答案 0 :(得分:6)

  

我可以与其他成员初始化会员吗?

是的,只要其他成员已经初始化;即只要他们的声明在成员初始化之前到来。

  

复制构造函数和[复制赋值运算符]是编译器自动添加的唯一函数吗?

它还会隐式声明一个析构函数,它将使用它的析构函数来销毁_x

在C ++ 11中,还隐式声明了移动构造函数(Class(Class&&))和移动赋值运算符(Class& operator=(Class&&)),除非您声明了复制或移动构造函数,或者复制或移动赋值运算符。

请注意,您的构造函数模板不是复制构造函数,而是使用隐式构造函数:

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

根据标准,这种行为完全正常吗?

是的,见第12章。

  

我是否保证不会自动添加空构造函数并且Class<int> x;会写"My normal constructor"

是的,如果您根本没有声明任何构造函数,则只会隐式声明默认构造函数。