调用方法作为 R 值

Call a method as a R-Value

我正在阅读一本关于 C++11、14 和 17 的新特性的书。在关于 move-语义的章节中,作者使用以下 class 作为示例:

class DataObject {
public:
  DataObject(int n, int v): data_(new int[n]), size_(n) {
    std::fill(data_, data_ + size_, v);
  }
  virtual ~DataObject() {
    delete[] data_;
  }
  ... //copy constructor, assignment operator

private:
  int* data_;
  int size_;
}

现在,他介绍了重载方法 getData(),其中 returns data_ 作为 L 值或 R 值:

//For L-Value
int* getData() const& {
  int* result(new int[size_]);
  copy(data_, data_ + size_, result);
  return result;
}

//For R-Value
int* getData() && {
  return data_;
  data_ = nullptr;
  size_ = 0;
}

后面的例子如下:

DataObject do(4, 10);
int* data1 = do.getData();
int* data2 = DataObject(5, 20).getData();

我对 R 值 getData() 方法有疑问;这对我来说没有意义。我们 return data_ 然后我们将 data_ 设置为 nullptr... 但是函数已经保留 return data_data_ = nullptrsize_ = 0 怎么可能被执行?即使它们会被执行,析构函数也会在 DataObject(5,20) 超出范围时尝试删除 nullptr

问题: 有错误还是我误解了什么?离开函数后这两行怎么执行?

你的前提是错误的(强调我的):

The introduces the overloaded method getData() which returns data_ as a L- or a R-Value

&&& 指的是您调用方法的对象(就像 const 在那个地方所做的那样)而不是 return 类型。这就是示例所展示的内容:

DataObject do(4, 10);
int* data1 = do.getData();
//           ^ this is a l-value

int* data2 = DataObject(5, 20).getData();
//                ^ this is a r-value

现在回答您的实际问题:

We return data_ and then we set data_ to nullptr... but the function was left already with return data_

你完全正确,那段代码是胡说八道。 return 之后的语句永远不会被执行。

PS: 通常我避免在书本之类的东西上传播我的观点,但在这种情况下我必须告诉你,这是一个非常糟糕的例子,你应该远离那本书。