在实际环境中,使用gcc或MS Visual Studio,通过const引用传递大小相同或小于int的值类型是不是很糟糕?
即。编写这样的函数是不好的:
void f(const bool& b);
或
void f(const char& c);
而不是:
void f(bool b);
或
void f(char c);
我问的原因是我没有看到在这些情况下传递引用的好处,但也许我错过了一些东西。
答案 0 :(得分:18)
可能稍微不好,或者可能根本没有效果(取决于存储原始值的位置,优化程序有多好以及它如何决定处理代码)。
标准没有规定如何实现引用,但实际上编译器使用指针实现引用。因此,在一般情况下,bool&
将使用bool*
实现,这意味着要访问bool
,每次都需要额外的指针取消引用。由于bool
不大于指针,因此不会减少内存占用或减少字节复制以抵消此缺点。
因此,公认的做法是将原语作为值传递,因为它更有效。当然,虽然传递这样的引用并不会真正炸毁任何东西,除非你在循环中访问值,否则可能不会产生任何可测量的差异。
答案 1 :(得分:11)
除了性能之外,实际上有些情况会导致不同的行为。
例如,传递const
引用可确保函数不能更改引用变量的值,但另一个线程可能会这样做。如果您通过引用传递(即使使用const
),您将看到这些更改,如果您按值传递,则不会。
此外,界面的定义限制了您可以对函数内部的变量执行的操作。考虑这个例子:
int foo(int a) {
a = 5; // valid
}
int bar(const int& a) {
a = 5; // compiler-error
}
如果您通过引用传递,并且要修改变量的值以供本地使用,则需要进行额外的复制。如果您按值传递,则表示您已有副本。
答案 2 :(得分:2)
一个原因是你想向其他程序员传达价值是不变的,虽然const bool
就足够了,但在某些情况下可能会更清楚。
答案 3 :(得分:1)
我认为最好传递内置类型by value
而不是const reference
,因为它实际上更快。在通过引用传递的情况下,您需要创建引用(即获取地址),然后在使用变量时取消引用。在大多数情况下,无论如何都会通过编译器对其进行优化
答案 4 :(得分:0)
虽然理论上它不是一个好主意,因为引用通常使用指针实现。但是,每个合理的编译器都应该足够智能,以识别by-const-reference和基本类型的by-value之间的语义无差异。
如果您有某种模板化接口必须适用于复杂类型和基本类型,并且您不希望过多的特化开销(最简单的示例:std::vector
),通常您无法选择。但是如果你有一个选择,那么首选传递基本类型的值。
答案 5 :(得分:-1)
真的没关系,通过价值会使你的代码更清晰,因此被视为良好的做法。