当我取消移动构造函数A(A&&)时,下面的代码段会发生什么?

时间:2015-08-10 19:21:18

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

下面的代码段似乎没问题,我相信A a(std::move(b).toA());中的声明main()会调用类A的隐式声明的移动构造函数,因为A没有'具有用户定义的复制构造函数,它没有用户定义的复制赋值运算符,它没有用户定义的移动赋值运算符,也没有用户定义的析构函数(参见§12.8/ 9 N4140)。但是,当我取消注释下面的移动构造函数A(A&&) { std::cout << "move A" << '\n'; }时,我会收到Illegal instruction消息。见live example。这是为什么?

#include <iostream>
#include <memory>
class A {
public:
//    A(const A&) { std::cout << "copy A" << '\n'; }
//    A(A&&) { std::cout << "move A" << '\n'; }
    A(std::unique_ptr<int>&& u_ptr) : u_ptr(std::move(u_ptr)) {}
    const int& getInt() { return *u_ptr; }

private:
    std::unique_ptr<int> u_ptr;
};

class B {
public:
    B(int u_ptr) : u_ptr(new int(u_ptr)) {}
    A toA() && { return A(std::move(u_ptr)); }

private:
    std::unique_ptr<int> u_ptr;
};

int main() {
    B b(-1);
    A a(std::move(b).toA());
    std::cout << a.getInt() << '\n';
    return 0;
}

1 个答案:

答案 0 :(得分:5)

您的移动构造函数定义没有执行隐式定义的定义 - 它不移动构造u_ptr数据成员。因此,a.u_ptr是默认构建的,内部int*初始化为nullptr。然后,对a.getInt()的调用会尝试取消引用导致崩溃的nullptr

如下所示定义移动构造函数,代码将正常运行

A(A&& other) : u_ptr(std::move(other.u_ptr)) { std::cout << "move A" << '\n'; }