为按引用传递的c++函数提供引用类型的参数



我有一个很无聊的问题。

我认为,当您对c++函数进行按引用传递时,您实际上必须传递引用类型的实参(或形参?)但我从我正在学习的资源中看到,基本上在网上,我错了。

那么,这两者之间的真正区别是什么?为什么它们都有效?

scenario_1

#include <iostream>
int sum(const int& a, const int& b)
{
return (a + b);
}
int main()
{
const int a1 {2};
const int a2 {20};

std::cout << sum(a1, a2) << "n";
}

scenario_2

#include <iostream>
int sum(const int& a, const int& b)
{
return (a + b);
}
int main()
{
const int& a1 {2};
const int& a2 {20};

std::cout << sum(a1, a2) << "n";
}

c++有一长串规则,根据这些规则,一种类型的对象可以自动转换为另一种相关类型的对象。

例如,您可能有一个以const char *作为参数的函数,例如:

size_t strlen(const char *);

尽管它的参数是一个const char *,你有很好的机会成功传递一个非const的char数组给这个函数:

char buffer[256];
// Some code.
size_t l=strlen(buffer);

你关于引用的问题是完全一样的。可修改左值可自动转换为对相同类型的const对象的引用。你不用担心,编译器会为你做的。

还有很多其他的规则。这可能是您第一次了解c++的自动转换规则(或隐式转换规则)。这不会是最后一次。

那么,这两者之间的真正区别是什么,为什么它们都是工作吗?

没有实际的区别。这两个版本之间有一些迂腐的差异,但它们产生相同的逻辑结果。

引用指向其他地方的对象实例。当您使用对对象的引用时,对该引用的所有使用都与使用原始对象一样。这允许一个T&引用另一个T&,等等——但最终它必须从某处引用一个现有的T对象

这回答了"为什么它工作"你问题的一部分;,因为引用只是指向实例本身。


你的另一个问题的答案是"这两者的真正区别是什么";有点复杂。c++中的const引用有点奇怪,因为它们能够扩展临时对象的生存期

c++中的所有对象都有生命周期。通常,对象的生命周期从创建时开始,并在其作用域结束时结束——无论这只是表达式的全部部分,还是直到文字结尾的}作用域。引用查看生命周期,但通常不影响生命周期(这意味着,例如,返回对临时对象的引用将产生一个悬空引用指向一个不再存在的对象)。

另一方面,const引用将生命周期延长到封闭作用域的长度。所以当你输入:

const int& a1 {2};
const int& a2 {20};

你实际上做的是创建两个临时未命名对象,值为220,const int&扩展这些变量的生存期

这就好像你做了这样的事情:

const int __unnamable_value_1 = 2;
const int __unnamable_value_2 = 20;
const int& a = __unnamable_value_1;
const int& b = __unnamable_value_2;
在大多数情况下,我建议不要考虑c++的这种奇怪之处。如果您想创建一个命名值,请按值创建它(例如const T)。如果你想引用一个可能不在同一位置构造的对象,请使用引用(const T&)。

最新更新