【问题标题】:moving temporary value using rvalue reference使用右值引用移动临时值
【发布时间】:2014-09-22 01:13:47
【问题描述】:

我正在尝试精简移动语义,并编写了这个示例。我想将临时 r 值移动到堆栈上的对象中。

class MemoryPage
{
    public:

    size_t size;
    MemoryPage():size(0){
    }
    MemoryPage& operator= (MemoryPage&& mp_){
        std::cout << "2" <<std::endl;
        size = mp_.size;
        return *this;
    }
};
MemoryPage getMemPage()
{
    MemoryPage mp;
    mp.size = 4;
    return mp;
}
int main() {
    MemoryPage mp;
    mp = getMemPage();
    std::cout << mp.size;
    return 0;
}

我在 getMemPage() 返回时收到此错误:

error: use of deleted function 'constexpr MemoryPage::MemoryPage(const MemoryPage&)'

【问题讨论】:

  • MemoryPage 的复制(和移动)构造函数被隐式定义为已删除/未声明,因为您提供了自定义移动赋值运算符。返回一个对象,如return mp; 需要一个复制或移动构造函数(即使它没有被调用)。确保遵循五法则。
  • 顺便说一下,错误信息应该告诉你 DyP 做了什么。不确定您是否出于问题的目的对其进行了裁剪。 note: 'constexpr MemoryPage::MemoryPage(const MemoryPage&amp;)' is implicitly declared as deleted because 'MemoryPage' declares a move constructor or move assignment operator

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


【解决方案1】:

copy constructor 是:

[...] 如果满足以下任一条件,则定义为已删除:

  • T 有一个用户定义的移动构造函数或移动赋值运算符

为了解决眼前的问题,你只需提供一个拷贝构造函数,即:

MemoryPage(const MemoryPage&) { }

但是,正如 cmets 中所述,咨询Rule-of-Three becomes Rule-of-Five with C++11? 是个好主意。特别是,本段总结了如果您忽略提供任何特殊成员函数可能会遇到的问题:

注意:

  • 不会为显式声明任何其他特殊成员的类生成移动构造函数和移动赋值运算符 功能

  • 不会为显式声明移动构造函数或移动赋值的类生成复制构造函数和复制赋值运算符 运营商

  • 具有显式声明的析构函数和隐式定义的复制构造函数或隐式定义的复制赋值运算符的类是 认为已弃用。

为便于阅读而格式化

因此,在编写处理内存管理的类时最好提供所有五个特殊成员函数,即:

class C {
  C(const C&) = default;
  C(C&&) = default;
  C& operator=(const C&) & = default;
  C& operator=(C&&) & = default;
  virtual ~C() { }
};

【讨论】:

  • 您甚至可以默认虚拟 dtor。
  • 我认为答案的一个重要部分是 where OP 的代码中需要复制/移动 ctor。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2021-08-26
  • 2013-02-14
相关资源
最近更新 更多