这是否有区别:
MyClass c = getMyClass();
calculate(c.value);
和此:
calculate(getMyClass().value);
在性能和内存分配范围内?
答案 0 :(得分:5)
是的,存在相当严重的差异。在第一种情况下,c
是左值,并且在范围结束之前不会销毁它。这可能会延迟reosurce清理等有用的事情。更有问题的是,它是一个左值意味着它不能被移动,但必须被复制,这对于许多类来说是低效的,但对于一些非常重要的类来说是非法的,例如unique_ptr
。
在第二种情况下,编译器立即清除临时文件,因此所有资源都会立即释放,并且它是一个rvalue,使编译器可以更自由地优化并允许移动语义。
当value
是成员函数或成员函数时,这仍然是正确的,因为两者都可以从父对象继承值类别。
您应始终将对象的范围限制在所需的最小范围内,如果您以后不需要访问c
,则应使用临时对象。
答案 1 :(得分:2)
有区别吗?是的,非常重要。给读者。
编译器可能不在乎你编写它的方式。发出的代码,使用的空间和执行时间非常接近,他们不值得花费一毫秒的思考时间。
但是你的读者会关心。在某些情况下,第一种形式提供了提供有用变量名称的机会,以帮助解释您的意图。在其他情况下,缺少声明的变量使它成为一个单一的语句,并且可以更容易阅读,特别是如果它们有很多。
请接受这个想法,你应该关心编译器的想法,并开始关注读者的想法!顺便说一下,你是六个月之后的读者之一。
答案 2 :(得分:0)
都能跟得上!它只是评估getMyClass().value
表达式并将其发送到方法的参数。
当然,参数本身是一个作用于方法的局部变量。
答案 3 :(得分:0)
第一个表单告诉编译器创建MyClass
的新实例。如果getMyClass()
返回对const
的{{1}}引用,则您不需要新实例。您的编译器可能会优化新实例,但在这种情况下,如果MyClass
是MyClass::value()
函数,我更愿意编写
const
即使const MyClass& c = getMyClass();
calculate(c.value());
返回一个简单的getMyClass()
,从技术上讲,您仍然可以声明
MyClass
;编译器只会强制const MyClass& c
的新实例
只要MyClass
在范围内,就会保持存在,类似于如果发生的情况
你声明c
,虽然有争议这是否是好的
编码实践(见here或here)。
正如已经指出的那样,第一种形式创建的实例一直存在,直到范围结束,尽管你可以通过添加额外的MyClass c
和{{{{}}来最小化效果。 1}}:
{
就个人而言,在大多数情况下,我更喜欢创建一个局部变量,其名称告诉我一些关于我传递给}
函数的内容,以使代码更加自我记录。一个例外是当我必须在不同的值上连续几次调用{
MyClass c = getMyClass();
calculate(c.value());
}
时,在这种情况下,如果在连续的代码行上发生调用而没有声明任何新变量,则可能更清楚地发生了什么。