要从函数中使用返回的对象,有人可以告诉我为什么在这段代码中情况1,3,4可以但不是2吗?
#include <iostream>
using namespace std;
class X {
int i;
public:
X(int ii = 0) : i(ii) {};
void modify() { i++; };
};
X f1() { return X(1); }
// Pass by non-const reference
void f20(X& x) { x.modify(); }
// Pass by const reference
void f21(const X& x) { }
// Pass by value
void f22(X x) { x.modify(); }
int main() {
f1() = X(2); // 1. OK
//! f20(f1()); // 2. Bad
f21(f1()); // 3. OK
f22(f1()); // 4. OK
}
谢谢!
答案 0 :(得分:1)
因为临时符号不能与非const
的左值引用绑定。
我见过的主要理由是,否则(与Visual C ++语言扩展一样)是一个像
这样的函数void increment( int& value ) { ++value; }
可能会被称为
auto main() -> int
{
increment( 2+2 );
}
但我不确定这完全令人信服。
这些规则确实有助于编写大量代码,但是作为Visual C ++语言扩展(允许类类型的绑定)的例证,它并不重要,普通代码中的问题也不多。
顺便说一下,请注意临时对象不是const
,除非它已被声明为此类。特别是,您可以在其上调用非const
成员函数,例如f1().modify()
。您无法将其绑定到非const
的左值引用。
答案 1 :(得分:0)
f1()方法返回X类型的临时对象。
=运算符可以应用于X类型的对象,即使之后对象本身不可用。
f21()需要const引用(即在该函数中不应该更改的内容),因此不会检查引用是否有效。
f22()期望值本身在函数内部被修改,然后修改将丢失。
f20()需要一个引用,即在此函数内所做的更改应该应用于该函数之外的对象。但是它得到了一个临时对象的引用,因此就是问题。
如果要返回对非临时对象的引用,则函数必须如下所示:
X& f1() { return *(new X(1)); }
然后你必须要注意删除这个对象。