C++ 何时在函数 args 中使用 const 和 const 引用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3967177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 14:09:18  来源:igfitidea点击:

When to use const and const reference in function args?

c++argumentsconst

提问by Tony The Lion

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.

在编写具有传递给它的 args 的 C++ 函数时,根据我的理解,如果您可以保证对象不会被更改,则应始终使用 const 或如果指针不会更改则使用 const 指针。

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?

什么时候使用 const 引用,例如,与仅通过指针传递相比有什么优势?

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?

这个什么void MyObject::Somefunc(const std::string& mystring)什么会在具有常量字符串,如果一个字符串其实已经是不可改变的对象呢?

回答by

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

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

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

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

void modifies(T &param);
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.

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

Compare const ref to by value

按值比较 const ref

void doesnt_modify(T const &param);
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++.)

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

Compare const pointer to non-modifying plus overload

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

void optional(T const *param=0);
// vs
void optional();
void optional(T const &param); // 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

Const by value 是一个实现细节

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:

这些声明实际上是完全相同的功能!当按值传递时,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

回答by Bj?rn Pollex

The general rule is, use constwhenever possible, and only omit it if necessary. constmay 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).

一般规则是,const尽可能使用,并且仅在必要时省略它。const可能使编译器能够优化并帮助您的同行了解您的代码打算如何使用(并且编译器会发现可能的误用)。

As for your example, strings are not immutable in C++. If you hand a non-constreference 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).

至于你的例子,字符串在 C++ 中不是一成不变的。如果您const将一个字符串的非引用传递给一个函数,该函数可能会修改它。C++ 没有内置于语言中的不变性概念,您只能使用封装和const(尽管永远不会防弹)来模拟它。

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.

在思考@Eamons 评论并阅读一些内容后,我同意优化不是使用const. 主要原因是有正确的代码。

回答by Cheers and hth. - Alf

The questions are based on some incorrect assumptions, so not really meaningful.

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

std::stringdoes not model immutable string values. It models mutable values.

std::string不建模不可变的字符串值。它为可变值建模。

There is no such thing as a "const reference". There are references to constobjects. The distinction is subtle but important.

没有“const 引用”这样的东西。有对const对象的引用。这种区别很微妙,但很重要。

Top-level constfor 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 constis pretty much meaningless as argument type in a pure declaration of a function. However, the constin std::string const&is not top level.

const函数参数的顶层只对函数实现有意义,对纯声明(编译器忽略它)没有意义。它不会告诉呼叫者任何事情。这只是对实现的限制。例如int const,作为纯函数声明中的参数类型,它几乎毫无意义。但是,constinstd::string const&不是顶级的。

Passing by reference to constavoids 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 constmay be optimized away or it may be implemented as a pointer. E.g., in 32-bit Windows an intis 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.

通过引用传递以const避免低效复制数据。通常,对于将数据传递给函数的参数,您可以通过int值传递小项目(例如),并通过引用传递可能较大的项目const。在机器代码中,对的引用const可能被优化掉,或者它可能被实现为一个指针。例如,在 32 位 Windows 中,anint是 4 个字节,一个指针是 4 个字节。因此,参数类型int const&不会减少数据复制,但对于头脑简单的编译器,可能会引入额外的间接性,这意味着效率稍低——因此存在小/大区别。

Cheers & hth.,

干杯 & hth.,

回答by Adesit

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.

const 引用相对于 const 指针的主要优点如下:明确参数是必需的,不能为 NULL。反之亦然,如果我看到一个 const 指针,我会立即假设它不是引用的原因是该参数可能为 NULL。