[英]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+
. 如果
a
和b
是同一类的对象,请考虑使用二元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 * c
和b * c
的值并将它们存储在某个位置-无法将它们存储在a
或b
或c
。 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.