使用右值引用移动临时值

moving temporary value using rvalue reference

本文关键字:移动 引用      更新时间:2023-10-16

我正在尝试精简移动语义,我写了这个例子。我想将临时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&)'

复制构造函数是:

[…]定义为删除,如果以下任何条件成立:

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

为了解决眼前的问题,您只需提供一个复制构造函数,即:

MemoryPage(const MemoryPage&) { }

然而,正如评论中所指出的,用C++11将"三条规则"变成"五条规则"是一个好主意。特别是,本段总结了如果您忽视提供任何特殊成员功能,您可能会遇到的问题:

注意:

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

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

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

格式化为可读性

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

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