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

标签 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;
}

最佳答案

您的移动构造函数定义没有执行隐式定义的操作 - 它不会移动构造 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'; }

关于c++ - 当我取消注释移动构造函数 A(A&&) 时,下面的代码片段会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31927472/

相关文章:

javascript - 使用 emscripten 将 c++ 代码编译为 javascript 以计算两个数字的总和。练习

c++ - 在基于 C++ 范围的 for 循环中获取当前元素的索引

c++ - 当派生对象绑定(bind)到基类引用时复制/移动/转换语义?

c++ - 运算符(operator)覆盖错误

C++ 为什么在不使用删除的函数时编译器失败并显示错误代码 C2280

具有移动和复制构造函数的类中的 C++ 代码重复

c++ - 将一个预先声明但未初始化的 vector 设置为另一个的别名

c++ - 如何检查 makefile 中已定义符号(Eclipse-> 路径和符号)的值?

c++ - 显式实例化泛型结构的泛型成员函数

c++ - 如何正确解决 const std::string& 和 const std::vector<string>& 歧义?