我正在阅读一本关于C ++ 11,14和17的新功能的书。在关于move
- 语义的章节中,作者使用以下类作为示例:
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()
,它返回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()
方法有疑问;这对我没有意义。我们返回data_
,然后我们将data_
设置为nullptr
...但该函数已经保留return data_
。如何执行data_ = nullptr
和size_ = 0
?即使它们被执行,析构函数也会在nullptr
超出范围时尝试删除DataObject(5,20)
。
问题: 有错误还是我误解了什么?离开函数后如何执行这两行?
答案 0 :(得分:4)
你的前提是错的(强调我的):
引入了重载方法getData(),其中返回data_ as L-或R-值
&
和&&
引用您调用方法的对象(就像const
在该位置所做的那样)而不是返回类型。这就是示例所展示的内容:
DataObject do(4, 10);
int* data1 = do.getData();
// ^ this is a l-value
int* data2 = DataObject(5, 20).getData();
// ^ this is a r-value
现在问你的实际问题:
我们返回data_然后我们将data_设置为nullptr ...但函数 已经留下了返回数据_
你是完全正确的,那段代码是无稽之谈。返回后的语句无法执行。
PS:通常我会避免在书籍上传播我的意见,但在这种情况下,我必须告诉你这是一个非常糟糕的例子,你应该远离那本书。