将移动构造函数自动初始化未列出的成员?

时间:2016-07-04 06:50:40

标签: c++ c++11 move-constructor

如果我有这门课程:

class Foo {
public:
    Foo() = default;

    // version 1 move constructor
    Foo(Foo &&f) : v_() {
        v_.swap(f.v_);
    }

    // version 2 move constructor
    Foo(Foo &&f) : v_(), m_() {
        v_.swap(f.v_);
    }

private:
    std::vector<int> v_;
    std::mutex m_;
};

void bar(Foo &&f) {
    // construct a new object from f
    Foo f2(std::move(f)); // f2's value before calling constructor is undefined
}

2个移动构造函数之间有什么区别吗?是否在版本1中自动初始化互斥锁m_或者我是否需要在版本2中明确列出它?

请注意,我没有交换互斥锁,没有必要这样做(我明确将移动构造函数标记为非线程安全,因为它可以& #39;由于其他原因)。

1 个答案:

答案 0 :(得分:4)

在这种情况下,这两个构造函数之间绝对没有区别。

规则是:构造函数的成员初始化列表中未列出的每个数据成员都是 default-initialised。对于类类型,这意味着调用默认构造函数。这就是std::mutex的情况,因此可以安全地省略初始化m_()

非类型(int,指针等)发挥作用时会有所不同。对于这些,默认初始化不会做任何事情(它会使它们具有不确定的值),因此如果您希望对这些成员进行初始化,则必须在列表中明确列出它们。即使仅将()作为初始化列出,也会将其从默认初始化转换为值初始化,,这意味着对这些类型初始化为零值。