1

我最近一直在仔细研究 C++ 类别。lvalue 和 rvalue 之间的区别似乎很清楚,但是当谈到 prvalue 和 xvalue 时,我感到困惑。
给出下面的例子:

#include <iostream>
using std::cout;
using std::endl;
using std::move;
class Type {
public:
    int value;
    Type(const int &value=0) :value(value) {}
    Type(const Type &type) :value(type.value){}
    Type(Type &&type) noexcept :value(type.value) {}
    Type &operator= (const Type &type) {
        value = type.value;
        return *this;
    }
    Type &operator=(Type &&type) noexcept{
        value = type.value;
        return *this;
    }
};
Type foo1(const Type &value) {
    return Type(value);
}
Type &&foo2(const Type &value) {
    return Type(value);
}
int main() {
    Type bar1(123);
    cout << foo1(bar1).value << endl;
    cout << foo2(bar1).value << endl;
    Type bar2;
    bar2 = foo1(bar1);
    cout << bar2.value << endl;
    bar2 = foo2(bar1);
    cout << bar2.value << endl;
    return 0;
}

运行示例,控制台输入:
123
123
123
-858993460
谁能解释为什么它在最后一个输出中给出了一个意外的值?
这个例子展示了 xvalue 的什么特征?

4

1 回答 1

2

foo2正在返回绑定到临时的引用,该引用立即被销毁;它总是返回一个悬空引用

在 return 语句中临时绑定到函数的返回值不会被扩展:它在 return 表达式的末尾立即被销毁。这样的函数总是返回一个悬空引用。

对返回的引用取消引用,foo2(bar1).valuebar2 = foo2(bar1);导致 UB;一切皆有可能。

另一方面,foo1没有这样的问题。返回值从临时对象中移出。

于 2020-10-16T15:50:27.747 回答