使用赋值给函数返回值的局部变量或直接使用函数

Using local variable assigned to return value of a function or using function directly

本文关键字:函数 局部变量 返回值 赋值      更新时间:2023-10-16

有区别吗?
MyClass c = getMyClass();
calculate(c.value);

:

calculate(getMyClass().value);

在性能和内存分配的范围内?

是的,有相当严重的区别。在第一种情况下,c是一个左值,在作用域结束之前它不会被销毁。这可能会延迟一些有用的事情,比如资源清理。更有问题的是,它是一个左值意味着它不能被移动,但必须被复制,这对许多类来说是低效的,但对一些非常重要的类来说是完全非法的,比如unique_ptr

在第二种情况下,编译器立即清理临时值,因此所有资源都被立即释放,并且它是一个右值,使编译器可以更自由地优化并允许移动语义。

value是成员或成员函数时仍然如此,因为两者都可以从它们的父对象继承值类别。

您应该始终将对象作用到所需的最小作用域,如果以后不需要访问c,那么您应该使用临时的

有区别吗?是的,确实如此。给读者。

编译器根本不在乎你怎么写。所发出的代码,所使用的空间和执行时间是如此接近,以至于不值得花费一毫秒的思考时间。

但是你的读者会在意的。在某些情况下,第一个表单提供了提供有用的变量名的机会,以帮助解释您的意图。在其他情况下,缺少声明的变量使其成为单个语句,并且可以更容易阅读,特别是在有很多变量的情况下。

请不要再想着你应该关心编译器的想法,而应该开始更多地关心你的读者的想法!顺便说一下,你是六个月后的读者之一。

不行!它仅仅计算getMyClass().value表达式并将其发送给方法的参数。当然,参数本身是一个局部变量,作用域是该方法。

第一种形式告诉编译器创建一个新的MyClass实例。如果getMyClass()返回constMyClass的引用,则实际上不需要创建新的实例。您的编译器可能会将新实例优化掉,但在这种情况下,如果MyClass::value()const函数,我更喜欢写

const MyClass& c = getMyClass();
calculate(c.value());

即使getMyClass()返回一个简单的MyClass,技术上你仍然可以声明const MyClass& c;编译器将强制使用MyClass的新实例只要c在作用域中,就会保持存在,类似于你声明MyClass c,尽管有关于这是否是一个好的争论编码练习(见这里或这里)。

正如已经指出的那样,由第一种形式创建的实例一直存在到作用域结束,尽管在这种情况下可以通过添加一对额外的{}来最小化效果:

{
  MyClass c = getMyClass();
  calculate(c.value());
}

就我个人而言,在大多数情况下,我更喜欢创建一个局部变量,它的名称告诉我要传递给calculate函数的内容,以使代码更具自文档性。一个例外是当我必须在不同的值上连续调用calculate几次时,在这种情况下,如果调用发生在连续的代码行上而不声明任何新变量,则可能更清楚发生了什么。