例如有这样一个人为的类
class Example
{
public:
int x = 0;
Example& get_ref()
{
return *this;
}
};
这样的一行自然会导致错误,因为我们对右值进行了非常量引用
Example& example = Example();
但是为什么这个例子不会导致错误,如果它是相同的,我们甚至可以通过这个链接改变状态?(或者不一样?)
Example& example = Example().get_ref();
指针如何this
获取临时对象的地址?我在引擎盖下想象它是这样的Example* this = &(объект вызывающий метод)
,并没有真正考虑过,因为我从来没有从右值调用方法,也没有调用过并且没有考虑过......
在第二个示例中,临时对象被立即删除,因此如果您继续使用链接,它将是 UB。
好吧,它只是需要。不能直接取右值1的地址是万无一失的,人为的限制。
此外,了解对象和表达式之间的区别也很有用。
对象是在运行时创建的(在内存中的某处),表达式是代码中引用该对象的代码。
在这里你已经执行
Example().get_ref();
了,并且在内存中创建了一个临时对象。表达式Example()
引用这个对象,这个表达式是一个右值。在方法
get_ref()
中,表达式*this
引用同一个对象,该表达式是一个左值。类别 (lvalue/rvalue/...) 仅用于表达式,对象没有它们。所有对象2都有地址,甚至是临时地址。
1更准确地说,取xvalue的地址。prvalue 本身没有地址,但它可以具体化为具有地址的 xvalue 。
Example()
当一个方法被拉到它上面时,你的prvalue就会实现。2在这里你可以争论,但寄存器中的对象是什么?该标准允许您获取任何对象的地址(即使是临时对象 - 但不是直接的,而是例如在方法内部,就像您所做的那样)。对你来说,所有对象似乎都在内存中。编译器只能通过as-if 规则将它们放入寄存器- 也就是说,如果编译器决定将对象放入寄存器,那么它应该为您不知不觉地做到这一点。
通过表达式
Example& example = Example();
你引用一个不存在的对象,也就是说,左操作数是一个引用,而右操作数是一个对象。在表达式中:第一个和第二个表达式都是引用,所以它们不一样,也不是错误。另一件事是这个表达式后面没有对象。嗯,这有点像写:
如您所知,在此代码之后链接变得无效