简体   繁体   English

C ++中的临时对象

[英]Temporary objects in C++

I was going through reference return and came across temporary objects. 我正在经历参考返回,并且遇到了临时对象。 I don't understand how to identify them. 我不知道如何识别它们。 Please explain using this example: 请使用以下示例进行说明:

If a and b are objects of same class, consider binary operator+ . 如果ab是同一类的对象,请考虑使用二元operator+ If you use it in an expression such as f(a+b) , then a+b becomes temporary object and f has to of form f(const <class name>&) or f(<class name>) . 如果在表达式f(a+b)使用它,则a+b成为临时对象,并且f的形式必须为f(const <class name>&)f(<class name>) It can't be of form f(<class name>&) However, (a+b).g() is perfectly alright where g() can even change contents of object returned by a+b . 它的形式不能为f(<class name>&)但是, (a+b).g()完全可以,其中g()甚至可以更改a+b返回的对象的内容。

When you say f(a + b) , the parameter of f needs to bind to the value with which the function was called, and since that value is an rvalue (being the value of a function call with non-reference return type)*, the parameter type must be a const-lvalue-reference, an rvalue-reference or a non-reference. 当您说f(a + b)f的参数需要绑定到调用该函数的值,并且由于该值是一个右值(即具有非引用返回类型的函数调用的值)* ,参数类型必须是const-lvalue-reference,rvalue-reference或非引用。

By constrast, when you say (a + b).g() , the temporary object is used as the implicit instance argument in the member function call, which does not care about the value category. 相比之下,当您说(a + b).g() ,临时对象用作成员函数调用中的隐式实例参数,该成员函数并不关心值类别。 Mutable values bind to non-const and const member functions, and const values only bind to const member functions (and similarly for volatile ). 可变值绑定到非const和const成员函数,而const值仅绑定到const成员函数(对于volatile )。

Actually, C++11 did add a way to qualify the value category of the implicit instance argument, like so: 实际上,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

*) this is the case for an overloaded operator as in this example, and also for built-in binary operators. *)在此示例中,重载运算符和内置二进制运算符都是如此。 You can of course make overloaded operators which produce lvalues, though going against the common conventions would probably be considered very confusing. 当然,您可以使产生左值的重载运算符,尽管违反通用约定可能会被认为非常混乱。

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

For a simple case, think of following piece of code: 对于简单的情况,请考虑以下代码:

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

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

Because func takes two integers, the program must calculate the values of a * c and b * c and store them somewhere -- it can't store them in a or b or c . 由于func接受两个整数,因此程序必须计算a * cb * c的值并将它们存储在某个位置-无法将它们存储在abc So the resulting code is equivalent to: 因此,生成的代码等效于:

int lhsParam = a * c;
int rhsParam = b * c;
return func(lhsParam, rhsParam);

Again, at the end of func() we return a calculate value, lhs + rhs . 同样,在func()的末尾,我们返回一个计算值lhs + rhs The compiler must store it in a new place. 编译器必须将其存储在新位置。

For integers and so forth this seems very simple, but consider instead 对于整数等等,这似乎非常简单,但请考虑

int function(std::string filename);
function("hello");

filename has to be a std::string , but you passed a const char* . filename必须是std::string ,但是您传递了const char* So what the compiler does is: 因此,编译器要做的是:

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

just like the previous example, but this time it is hopefully clearer that we're constructing a temporary object. 就像前面的示例一样,但是这次希望我们可以清楚地构造一个临时对象。

Note: The convention of calling them "somethingParam" is just for clarity in this answer. 注意:称呼它们为“ somethingParam”的约定只是为了使此答案更清楚。

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

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