使用分配的局部变量来返回函数的值或直接使用函数

时间:2014-06-24 06:12:56

标签: c++ performance compiler-construction

这是否有区别:

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

和此:

calculate(getMyClass().value);

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

4 个答案:

答案 0 :(得分:5)

是的,存在相当严重的差异。在第一种情况下,c是左值,并且在范围结束之前不会销毁它。这可能会延迟reosurce清理等有用的事情。更有问题的是,它是一个左值意味着它不能被移动,但必须被复制,这对于许多类来说是低效的,但对于一些非常重要的类来说是非法的,例如unique_ptr

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

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

您应始终将对象的范围限制在所需的最小范围内,如果您以后不需要访问c,则应使用临时对象。

答案 1 :(得分:2)

有区别吗?是的,非常重要。给读者。

编译器可能不在乎你编写它的方式。发出的代码,使用的空间和执行时间非常接近,他们不值得花费一毫秒的思考时间。

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

请接受这个想法,你应该关心编译器的想法,并开始关注读者的想法!顺便说一下,你是六个月之后的读者之一。

答案 2 :(得分:0)

都能跟得上!它只是评估getMyClass().value表达式并将其发送到方法的参数。 当然,参数本身是一个作用于方法的局部变量。

答案 3 :(得分:0)

第一个表单告诉编译器创建MyClass的新实例。如果getMyClass()返回对const的{​​{1}}引用,则您不需要新实例。您的编译器可能会优化新实例,但在这种情况下,如果MyClassMyClass::value()函数,我更愿意编写

const

即使const MyClass& c = getMyClass(); calculate(c.value()); 返回一个简单的getMyClass(),从技术上讲,您仍然可以声明 MyClass;编译器只会强制const MyClass& c的新实例 只要MyClass在范围内,就会保持存在,类似于如果发生的情况 你声明c,虽然有争议这是否是好的 编码实践(见herehere)。

正如已经指出的那样,第一种形式创建的实例一直存在,直到范围结束,尽管你可以通过添加额外的MyClass c和{{{{}}来最小化效果。 1}}:

{

就个人而言,在大多数情况下,我更喜欢创建一个局部变量,其名称告诉我一些关于我传递给}函数的内容,以使代码更加自我记录。一个例外是当我必须在不同的值上连续几次调用{ MyClass c = getMyClass(); calculate(c.value()); } 时,在这种情况下,如果在连续的代码行上发生调用而没有声明任何新变量,则可能更清楚地发生了什么。