何时在函数参数中使用 const 和 const 引用?
当编写一个传递给它的参数的 C++ 函数时,根据我的理解,如果可以保证对象不会更改,则应始终使用 const ;如果指针不会更改,则应始终使用 const 指针。
还有什么时候建议这种做法?
例如,什么时候会使用 const 引用?与仅通过指针传递它相比,有哪些优点?
如果一个字符串实际上已经是一个不可变的对象,那么这个 void MyObject::Somefunc(const std::string& mystring)
又如何呢?
When writing a C++ function which has args that are being passed to it, from my understanding const should always be used if you can guarantuee that the object will not be changed or a const pointer if the pointer won't be changed.
When else is this practice advised?
When would you use a const reference and what are the advantages over just passing it through a pointer for example?
What about this void MyObject::Somefunc(const std::string& mystring)
What would be the point in having a const string if a string is in fact already an immutable object?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不幸的是,询问是否添加 const 是一个错误的问题。
将非常量引用与传递非常量指针进行比较
这种情况主要与风格有关:您希望调用看起来像
call(obj)
还是call(&obj)?然而,有两点差异很重要。如果您希望能够传递 null,则必须使用指针。如果要重载运算符,则不能使用指针。
将 const ref 与 by value 进行比较
这是一个有趣的情况。经验法则是“复制成本低”类型通过值传递——这些类型通常是小类型(但并非总是如此)——而其他类型则通过 const ref 传递。但是,如果您无论如何都需要在函数中进行复制,则 应该通过按值。 (是的,这暴露了一些实现细节。C'est le C++。)
比较 const 指针与非修改加重载
这与上面的非修改情况相关,除了传递参数是选修的。这三种情况之间的差异最小,因此请选择让您的生活最轻松的一种。当然,非常量指针的默认值由您决定。
按值传递的 const 是一个实现细节
这些声明实际上是完全相同的函数! 当按值传递时,const 纯粹是一个实现细节。 尝试一下:
Asking whether to add const is the wrong question, unfortunately.
Compare non-const ref to passing a non-const pointer
This case is mostly about style: do you want the call to look like
call(obj)
orcall(&obj)
? However, there are two points where the difference matters. If you want to be able to pass null, you must use a pointer. And if you're overloading operators, you cannot use a pointer instead.Compare const ref to by value
This is the interesting case. The rule of thumb is "cheap to copy" types are passed by value — these are generally small types (but not always) — while others are passed by const ref. However, if you need to make a copy within your function regardless, you should pass by value. (Yes, this exposes a bit of implementation detail. C'est le C++.)
Compare const pointer to non-modifying plus overload
This is related to the non-modifying case above, except passing the parameter is optional. There's the least difference here between all three situations, so choose whichever makes your life easiest. Of course, the default value for the non-const pointer is up to you.
Const by value is an implementation detail
These declarations are actually the exact same function! When passing by value, const is purely an implementation detail. Try it out:
一般规则是,尽可能使用
const
,只有在必要时才忽略它。const
可以使编译器进行优化,并帮助您的同行了解您的代码的用途(并且编译器将捕获可能的误用)。至于你的例子,字符串在 C++ 中不是不可变的。如果将对字符串的非
const
引用传递给函数,该函数可能会修改它。 C++ 没有内置到语言中的不变性概念,您只能使用封装和 const 来模拟它(但这永远不会是无懈可击的)。在思考了 @Eamons 评论并阅读了一些内容之后,我同意优化并不是使用 const 的主要原因。主要原因是要有正确的代码。
The general rule is, use
const
whenever possible, and only omit it if necessary.const
may enable the compiler to optimize and helps your peers understand how your code is intended to be used (and the compiler will catch possible misuse).As for your example, strings are not immutable in C++. If you hand a non-
const
reference to a string to a function, the function may modify it. C++ does not have the concept of immutability built into the language, you can only emulate it using encapsulation andconst
(which will never be bullet-proof though).After thinking @Eamons comment and reading some stuff, I agree that optimization is not the main reason for using
const
. The main reason is to have correct code.这些问题是基于一些不正确的假设,因此没有真正的意义。
std::string
不会对不可变字符串值建模。它对可变值进行建模。不存在“常量引用”这样的东西。有对
const
对象的引用。这种区别很微妙但很重要。函数参数的顶级 const 仅对函数实现有意义,对纯声明(编译器忽略它)没有意义。它不会告诉调用者任何信息。这只是对实施的限制。例如,int const 作为函数的纯声明中的参数类型几乎没有意义。但是,
std::string const&
中的const
不是顶级。通过引用传递 const 可以避免低效的数据复制。一般来说,对于将数据传递到函数中的参数,您可以按值传递小项(例如
int
),并通过引用const
传递可能较大的项。在机器代码中,对const
的引用可以被优化掉或者可以被实现为指针。例如,在 32 位 Windows 中,int
为 4 个字节,指针为 4 个字节。因此,参数类型 int const& 不会减少数据复制,但对于头脑简单的编译器来说,可以引入额外的间接寻址,这意味着效率稍低——因此存在小/大区别。干杯&呵呵,,
The questions are based on some incorrect assumptions, so not really meaningful.
std::string
does not model immutable string values. It models mutable values.There is no such thing as a "const reference". There are references to
const
objects. The distinction is subtle but important.Top-level
const
for a function argument is only meaningful for a function implementation, not for a pure declaration (where it's disregarded by the compiler). It doesn't tell the caller anything. It's only a restriction on the implementation. E.g.int const
is pretty much meaningless as argument type in a pure declaration of a function. However, theconst
instd::string const&
is not top level.Passing by reference to
const
avoids inefficient copying of data. In general, for an argument passing data into a function, you pass small items (such as anint
) by value, and potentially larger items by reference toconst
. In the machine code the reference toconst
may be optimized away or it may be implemented as a pointer. E.g., in 32-bit Windows anint
is 4 bytes and a pointer is 4 bytes. So argument typeint const&
would not reduce data copying but could, with a simple-minded compiler, introduce an extra indirection, which means a slight inefficiency -- hence the small/large distinction.Cheers & hth.,
const 引用相对于 const 指针的主要优点如下:很明显,参数是必需的并且不能为 NULL。
反之亦然,如果我看到一个 const 指针,我立即假设它不是引用的原因是该参数可能为 NULL。
The main advantage of const reference over const pointer is following: its clear that the parameter is required and cannot be NULL.
Vice versa, if i see a const pointer, i immedeately assume the reason for it not being a reference is that the parameter could be NULL.