构造函数成员初始化列表说明

时间:2018-08-03 08:23:22

标签: c++

问题出在主题-我想我不明白成员初始化列表与构造函数主体中的直接初始化有何不同。

假设以下代码:

template<typename T>
class MyClass
{
public:
    explicit MyClass(const T& val) : val_(val) {}
private:
    T val_;
    MyClass(const MyClass &other) = delete;
    MyClass(const MyClass &&other) = delete;
    MyClass& operator=(const MyClass &other) = delete;
    MyClass& operator=(const MyClass &&other) = delete;
};

template<typename R>
class MyOtherClass
{
public:
    explicit MyOtherClass(const R& val)
    : stuff_(val)
    {
        //stuff_(val); <-- does not work
    }   
private:
    MyClass<R> stuff_;
};

int main()
{
    MyOtherClass<int> my_value(34);
}

所以,: stuff_(val)为何工作...{ stuff_(val); }时出现以下错误

error: no matching function for call to ‘MyClass<int>::MyClass()’
  {
  ^
test.cpp:5:11: note: candidate: MyClass<T>::MyClass(const T&) [with T = int]
  explicit MyClass(const T& val) : val_(val) {}
           ^
test.cpp:5:11: note:   candidate expects 1 argument, 0 provided

[P.S。]该代码包含模板,因为从一开始我就想问一个不同的问题,但无法在此代码段中重现。在我的生产代码中,我有类似的东西:

template<typename R>
class MyOtherClass
{
public:
    explicit MyOtherClass(const R& val)
    {
        stuff_(val); 
        another_stuff_(56);
    }   
private:
    MyClass<R> stuff_;
    MyClass<int> another_stuff_;
};

它仅在another_stuff_(56)上给我错误。试图找出目前的区别。

1 个答案:

答案 0 :(得分:2)

stuff_(val);与任何初始化语法都不匹配。它正在尝试将stuff_用作函子,并将val用作参数。

此外,当进入构造器主体时,stuff_的初始化已完成。换句话说,您不能在构造函数的主体中执行初始化(您可以执行赋值或其他操作)。如果指定成员初始化器列表,则在输入构造器之前,将调用适当的构造器以对其进行初始化。如果没有,它将被默认初始化(在您的示例中,失败是因为MyClass没有默认构造函数,如错误消息所述)。