不保证是坏的。但在这种特定情况下是不必要的。
在许多(或大多数)上下文中,引用被实现为变相的指针。您的示例恰好是其中一种情况。假设函数没有内联,参数b
将作为指针“在后台”实现。因此,您setA
在第一个版本中真正传递的是指向 的指针,int
即提供对您的参数值的间接访问的东西。在第二个版本中,您传递了一个立即数int
,即提供对您的参数值的直接访问的东西。
哪个更好,哪个更差?好吧,在许多情况下,指针的大小比 大int
,这意味着第一个变体可能会传递更大量的数据。这可能被认为是“不好的”,但由于这两种数据类型通常都适合硬件字长,因此可能不会产生明显的差异,尤其是在 CPU 寄存器中传递参数时。
此外,为了读取b
函数内部,您必须取消引用该伪装的指针。从性能的角度来看,这也是“不好的”。
这些是人们希望通过值传递任何小尺寸(小于或等于指针大小)的参数的形式原因。对于参数或更大的大小,通过 const 引用传递成为一个更好的主意(假设您没有明确要求副本)。
但是,在大多数情况下,一个简单的函数可能会被内联,这将完全消除两个变体之间的差异,无论您使用哪种参数类型。
const
在第二个变体中不必要的问题是另一回事。在第一个变体中,有const
两个重要目的:
1)它可以防止你修改参数值,从而保护实际参数不被修改。如果引用不是const
,您将能够修改引用参数,从而修改参数。
2) 它允许您使用右值作为参数,例如 call some_obj.setA(5)
。没有const
这样的电话是不可能的。
在第二个版本中,这都不是问题。无需保护实际参数不被修改,因为参数是该参数的本地副本。无论您对参数做什么,实际参数都将保持不变。SetA
并且无论是否声明参数,您都可以使用右值作为参数const
。
const
出于这个原因,人们通常不会对按值传递的参数使用顶级限定符。但是如果你声明它const
,它只会阻止你修改b
函数内部的本地。有些人实际上喜欢这样,因为它强制执行适度流行的“不要修改原始参数值”约定,因此您有时可能会看到在参数声明中使用顶级const
限定符。