使用赋值给函数返回值的局部变量或直接使用函数
Using local variable assigned to return value of a function or using function directly
与
有区别吗?MyClass c = getMyClass();
calculate(c.value);
:
calculate(getMyClass().value);
在性能和内存分配的范围内?
是的,有相当严重的区别。在第一种情况下,c
是一个左值,在作用域结束之前它不会被销毁。这可能会延迟一些有用的事情,比如资源清理。更有问题的是,它是一个左值意味着它不能被移动,但必须被复制,这对许多类来说是低效的,但对一些非常重要的类来说是完全非法的,比如unique_ptr
。
在第二种情况下,编译器立即清理临时值,因此所有资源都被立即释放,并且它是一个右值,使编译器可以更自由地优化并允许移动语义。
当value
是成员或成员函数时仍然如此,因为两者都可以从它们的父对象继承值类别。
您应该始终将对象作用到所需的最小作用域,如果以后不需要访问c
,那么您应该使用临时的
有区别吗?是的,确实如此。给读者。
编译器根本不在乎你怎么写。所发出的代码,所使用的空间和执行时间是如此接近,以至于不值得花费一毫秒的思考时间。
但是你的读者会在意的。在某些情况下,第一个表单提供了提供有用的变量名的机会,以帮助解释您的意图。在其他情况下,缺少声明的变量使其成为单个语句,并且可以更容易阅读,特别是在有很多变量的情况下。
请不要再想着你应该关心编译器的想法,而应该开始更多地关心你的读者的想法!顺便说一下,你是六个月后的读者之一。
不行!它仅仅计算getMyClass().value
表达式并将其发送给方法的参数。当然,参数本身是一个局部变量,作用域是该方法。
第一种形式告诉编译器创建一个新的MyClass
实例。如果getMyClass()
返回const
对MyClass
的引用,则实际上不需要创建新的实例。您的编译器可能会将新实例优化掉,但在这种情况下,如果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
几次时,在这种情况下,如果调用发生在连续的代码行上而不声明任何新变量,则可能更清楚发生了什么。
- 局部变量保留函数中的值
- 如何使用 C++ 中的继承函数访问派生类中的局部变量
- 如何在函数外部访问函数中局部变量的值?
- 赋予全局变量而不是局部变量优先级的函数 - (异常行为)
- 获取具有静态局部变量的绑定/推断捕获 lambda 的函数指针
- 函数局部静态变量:从性能角度来看的优点/缺点
- 是否可以影响 C++ 中回调函数的局部变量?
- 将共享指针传递给函数参数 - 将其分配给局部变量的正确方法是什么
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取
- C++ - 指向函数中局部变量的指针
- 如何在 C++ 的 lambda 函数中传递同名的局部变量和参数(使用此关键字)?
- Clang++ 6.0 内存清理器未报告返回值指示条件分支的函数中的未初始化局部变量
- 如何将局部变量传递给 lambda 函数
- 局部变量的作用域是块或函数
- 函数原型未初始化的局部变量
- 尝试声明函数的局部变量,但得到范围错误
- 为什么堆栈中的函数局部变量之间存在内存空间
- 返回函数局部变量作为引用
- 函数局部变量在函数调用之间保持不变
- 对静态函数局部变量的引用