C++ 移动构造函数会自动初始化未列出的成员吗?
如果我有这门课:C++ 移动构造函数会自动初始化未列出的成员吗?,c++,c++11,move-constructor,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_);
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
}
两个移动构造函数之间有什么区别吗?互斥锁在版本1中是自动初始化还是需要在版本2中显式列出
请注意,我没有交换互斥体,没有必要这样做,我只是显式地将move构造函数标记为非线程安全的,因为这不可能是由于其他原因。在这种情况下,这两个构造函数之间绝对没有区别 规则是:未在构造函数的成员初始化器列表中列出的每个数据成员都是默认初始化的。对于类类型,这意味着调用默认构造函数。这就是std::mutex的情况,因此可以安全地省略初始化m_
当非类类型int、指针等起作用时,会有区别。对于这些成员,默认初始化不起任何作用,它会给它们留下一个不确定的值,因此如果您希望初始化这些成员,您必须在列表中明确列出它们。即使仅与初始化一起列出,也会将其从默认初始化转换为值初始化,这意味着对此类类型使用零值进行初始化。No,没有区别。成员的移动构造函数WRT初始化没有什么特别之处。只要成员有默认构造函数,您就不需要显式初始化它,例如POD不需要,std::mutex不需要。@XerenNarcy区别不是POD/非POD类型,而是类/非类类型。POD结构仍将调用其概念上的默认构造函数。当然,他什么也不做。