繁体   English   中英

C ++中的临时对象

[英]Temporary objects in C++

我正在经历参考返回,并且遇到了临时对象。 我不知道如何识别它们。 请使用以下示例进行说明:

如果ab是同一类的对象,请考虑使用二元operator+ 如果在表达式f(a+b)使用它,则a+b成为临时对象,并且f的形式必须为f(const <class name>&)f(<class name>) 它的形式不能为f(<class name>&)但是, (a+b).g()完全可以,其中g()甚至可以更改a+b返回的对象的内容。

当您说f(a + b)f的参数需要绑定到调用该函数的值,并且由于该值是一个右值(即具有非引用返回类型的函数调用的值)* ,参数类型必须是const-lvalue-reference,rvalue-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

*)在此示例中,重载运算符和内置二进制运算符都是如此。 当然,您可以使产生左值的重载运算符,尽管违反通用约定可能会被认为非常混乱。

造成混淆的原因不是无法识别临时对象,在两种情况下a+b结果都是临时对象,而是错误地假设non const方法需要左值并且不接受临时对象,这是不正确的。

对于简单的情况,请考虑以下代码:

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的值并将它们存储在某个位置-无法将它们存储在abc 因此,生成的代码等效于:

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* 因此,编译器要做的是:

std::string filenameParam = "hello"; // construct a new object
function(filenameParam);

就像前面的示例一样,但是这次希望我们可以清楚地构造一个临时对象。

注意:称呼它们为“ somethingParam”的约定只是为了使此答案更清楚。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM