何时在函数参数中使用 const 和 const 引用?

发布于 2024-09-28 13:31:55 字数 268 浏览 1 评论 0原文

当编写一个传递给它的参数的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巷雨优美回忆 2024-10-05 13:31:55

不幸的是,询问是否添加 const 是一个错误的问题。

将非常量引用与传递非常量指针进行比较

void modifies(T ¶m);
void modifies(T *param);

这种情况主要与风格有关:您希望调用看起来像 call(obj) 还是 call(&obj)?然而,有两点差异很重要。如果您希望能够传递 null,则必须使用指针。如果要重载运算符,则不能使用指针。

将 const ref 与 by value 进行比较

void doesnt_modify(T const ¶m);
void doesnt_modify(T param);

这是一个有趣的情况。经验法则是“复制成本低”类型通过值传递——这些类型通常是小类型(但并非总是如此)——而其他类型则通过 const ref 传递。但是,如果您无论如何都需要在函数中进行复制,则 应该通过按值。 (是的,这暴露了一些实现细节。C'est le C++。

比较 const 指针与非修改加重载

void optional(T const *param=0);
// vs
void optional();
void optional(T const ¶m); // or optional(T param)

这与上面的非修改情况相关,除了传递参数是选修的。这三种情况之间的差异最小,因此请选择让您的生活最轻松的一种。当然,非常量指针的默认值由您决定。

按值传递的 const 是一个实现细节

void f(T);
void f(T const);

这些声明实际上是完全相同的函数! 当按值传递时,const 纯粹是一个实现细节。 尝试一下:

void f(int);
void f(int const) {/*implements above function, not an overload*/}

typedef void C(int const);
typedef void NC(int);
NC *nc = &f;  // nc is a function pointer
C *c = nc;  // C and NC are identical types

Asking whether to add const is the wrong question, unfortunately.

Compare non-const ref to passing a non-const pointer

void modifies(T ¶m);
void modifies(T *param);

This case is mostly about style: do you want the call to look like call(obj) or call(&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

void doesnt_modify(T const ¶m);
void doesnt_modify(T param);

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

void optional(T const *param=0);
// vs
void optional();
void optional(T const ¶m); // or optional(T param)

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

void f(T);
void f(T const);

These declarations are actually the exact same function! When passing by value, const is purely an implementation detail. Try it out:

void f(int);
void f(int const) {/*implements above function, not an overload*/}

typedef void C(int const);
typedef void NC(int);
NC *nc = &f;  // nc is a function pointer
C *c = nc;  // C and NC are identical types
万劫不复 2024-10-05 13:31:55

一般规则是,尽可能使用 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 and const (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.

伤痕我心 2024-10-05 13:31:55

这些问题是基于一些不正确的假设,因此没有真正的意义。

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, the const in std::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 an int) by value, and potentially larger items by reference to const. In the machine code the reference to const may be optimized away or it may be implemented as a pointer. E.g., in 32-bit Windows an int is 4 bytes and a pointer is 4 bytes. So argument type int 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.,

就是爱搞怪 2024-10-05 13:31:55

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文