C++通过Const引用并通过Const引用返回

Kir*_*ril 11 c++ reference const-correctness pass-by-reference

我试图了解返回const引用是否有任何好处.我有一个通常看起来像这样的阶乘函数:

unsigned long factorial(unsigned long n)
{
    return (n == 0) ? 1 : n * factorial(n - 1);
}
Run Code Online (Sandbox Code Playgroud)

我假设当我们通过const引用传递并且返回const引用时会有性能提升......但是 - const正确性总是让我感到困惑.

const unsigned long & factorial(const unsigned long& n)
{
    return (n == 0) ? 1 : n * factorial(n - 1);
}
Run Code Online (Sandbox Code Playgroud)

返回const引用是否有效?还有,有人可以告诉我:这有益吗?

Cos*_*ert 9

这是无效的.您无法返回对局部变量的引用.

MSVS C++编译器甚至提供以下警告:

main.cc : warning C4172: returning address of local variable or temporary
Run Code Online (Sandbox Code Playgroud)

对GCC不太确定,但结果可能是一样的.

  • 经验法则是:当您知道类型 - 按值传递基元时,传递按值封装单个基元的类,通过const引用传递其他所有内容.对于不透明的第三方类,请告诉他们的文档告诉您做什么(例如迭代器 - 按值传递).如果您事先不知道类型(例如,它是模板类型参数),请通过const引用并希望优化器将其删除不需要的地方:) (3认同)

Chr*_*isW 8

如果值的大小很小,则const引用不比值快.在这种情况下,值的类型long是IMO小(例如4到8个字节):因此const引用将不会更快.实际上它可能更慢,因为要获取引用的值,编译器可能需要发出将取消引用引用的代码(如解除引用指针).

鉴于引用是像指针一样(内部)实现的,当值的大小大于指针的大小时,我希望通过传递引用获得比传递值更好的性能(假设它甚至合法通过引用:对超出范围的局部变量的引用不合法).

  • 对内部变量*的指针/引用对表达式的生命周期是有效的,这就是std :: string的.c_str()和operator =有效的原因.这也是const char*monkey = myStr.c_str(); 然后在代码中的其他地方使用指针'monkey'是一个坏主意. (2认同)

Tha*_*tos 6

这里的const引用是不正确的 - 你要返回一个对局部变量的引用 - 这里是一个未命名的临时变量,1或者是结果n * factorial(n - 1).因为引用是函数中的局部变量,所以当引用到达调用者时,该局部变量已经超出范围,并且无效.

将const引用返回到大型结构化类型,当引用将在函数退出时存活时,您希望避免复制.通常,这意味着返回对参数或成员变量的引用(在类的情况下).