C ++中的临时对象

时间:2013-10-18 18:29:55

标签: c++ reference return

我正在通过引用返回并遇到临时对象。我不明白如何识别它们。请使用此示例解释:

如果ab是同一类的对象,请考虑二进制operator+。如果您在f(a+b)这样的表达式中使用它,那么a+b将成为临时对象,而f必须形成f(const <class name>&)f(<class name>)。它不能是f(<class name>&)格式但是,(a+b).g()完全没问题,g()甚至可以更改a+b返回的对象内容。

3 个答案:

答案 0 :(得分:4)

当你说f(a + b)时,f的参数需要绑定到调用函数的值,因为该值是一个rvalue(是非函数调用的值) -reference return type)*,参数类型必须是const-lvalue-reference,rvalue-reference或non-reference。

通过约束,当你说(a + b).g()时,临时对象被用作成员函数调用中的隐式实例参数,它不关心值类别。可变值绑定到非const和const成员函数,而const值只绑定到const成员函数(类似于volatile)。

实际上,C ++ 11 确实添加了一种方法来限定隐式实例参数的值类别,如下所示:

struct Foo()
{
    Foo operator+(Foo const & lhs, Foo const & rhs);

    void g() &;     // #1, instance must be an lvalue
    void g() &&;    // #2, instance must be an rvalue
}

Foo a, b;

a.g();            // calls #1
b.g();            // calls #1
(a + b).g();      // calls #2

*)这是本例中重载运算符的情况,也是内置二元运算符的情况。当然,您可以创建生成左值的重载运算符,但是违反常见约定可能会被认为非常混乱。

答案 1 :(得分:1)

你的困惑并非源于你无法识别临时对象,在这两种情况下a+b的结果都是临时对象,但错误的假设是非const方法需要左值并且不接受临时对象,这是不正确的。

答案 2 :(得分:1)

对于一个简单的案例,请考虑以下代码:

int func(int lhs, int rhs)
{
    return lhs + rhs;
}

int main() {
    int a = 1, b = 2, c = 3;
    return func(a * c, b * c);
}

因为func采用两个整数,程序必须计算a * cb * c的值并将它们存储在某处 - 它不能将它们存储在a或{{ 1}}或b。因此得到的代码相当于:

c

同样,在int lhsParam = a * c; int rhsParam = b * c; return func(lhsParam, rhsParam); 的末尾,我们返回一个计算值func()。编译器必须将它存储在新的位置。

对于整数等等,这似乎很简单,但请考虑

lhs + rhs

int function(std::string filename); function("hello"); 必须是filename,但您通过了std::string。那么编译器的作用是:

const char*

就像前面的例子一样,但是这次我们希望更清楚地构建一个临时对象。

注意:调用它们的惯例&#34; somethingParam&#34;这个答案只是为了清楚。