为按引用传递的 c++ 函数提供引用类型参数
providing a reference-type argument for pass-by-reference c++ function
我有一个很无聊的问题。
我想,当你为 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";
}
引用引用其他地方的对象实例。当您使用对对象的引用时,对该引用的所有使用就好像您在使用该原始对象一样。这允许一个 T&
引用另一个 T&
,等等——但最终它必须从 某处 .[= 引用现有的 T
对象。 23=]
这回答了您问题中“为什么它有效”的部分; 因为引用只是引用实例本身。
你的另一个问题“这两者之间的真正区别是什么”的答案有点复杂。 const
C++ 中的引用有点奇怪,因为它们能够延长临时对象的生命周期。
C++ 中的所有对象都有生命周期。通常,一个对象的生命周期从它们被创建时开始,并在它们的作用域结束时结束——无论这只是一个表达式的全部部分,还是直到文字结束的 }
作用域。引用查看那个生命周期,但通常不会影响生命周期(这意味着返回一个临时引用,例如会产生一个悬挂引用 到一个不复存在的对象)。
另一方面,const
引用将生命周期延长到封闭范围的长度。所以当你有:
const int& a1 {2};
const int& a2 {20};
您实际做的是创建两个 临时未命名对象,值为 2
和 20
,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&
).
C++ 有一个冗长且有时令人困惑的规则列表,根据这些规则,一种类型的对象自动转换为其他相关类型的对象。
例如,您可能有一个将 const char *
作为参数的函数,例如:
size_t strlen(const char *);
尽管它的参数是 const char *
,但您很有可能成功地将非常量 char
数组传递给此函数:
char buffer[256];
// Some code.
size_t l=strlen(buffer);
你关于参考文献的问题是完全一样的。可修改的左值可自动转换为对同一类型的 const 对象的引用。你不用担心,编译器会帮你完成。
还有许多其他规则。这可能是您第一次接触 C++ 的自动转换规则(或隐式转换规则)。这不会是你的最后一次。
So, what is the real difference between these two and why both of them
work?
没有实际区别。两个版本之间存在一些迂腐的差异,但它们产生相同的逻辑结果。
我有一个很无聊的问题。
我想,当你为 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";
}
引用引用其他地方的对象实例。当您使用对对象的引用时,对该引用的所有使用就好像您在使用该原始对象一样。这允许一个 T&
引用另一个 T&
,等等——但最终它必须从 某处 .[= 引用现有的 T
对象。 23=]
这回答了您问题中“为什么它有效”的部分; 因为引用只是引用实例本身。
你的另一个问题“这两者之间的真正区别是什么”的答案有点复杂。 const
C++ 中的引用有点奇怪,因为它们能够延长临时对象的生命周期。
C++ 中的所有对象都有生命周期。通常,一个对象的生命周期从它们被创建时开始,并在它们的作用域结束时结束——无论这只是一个表达式的全部部分,还是直到文字结束的 }
作用域。引用查看那个生命周期,但通常不会影响生命周期(这意味着返回一个临时引用,例如会产生一个悬挂引用 到一个不复存在的对象)。
const
引用将生命周期延长到封闭范围的长度。所以当你有:
const int& a1 {2};
const int& a2 {20};
您实际做的是创建两个 临时未命名对象,值为 2
和 20
,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&
).
C++ 有一个冗长且有时令人困惑的规则列表,根据这些规则,一种类型的对象自动转换为其他相关类型的对象。
例如,您可能有一个将 const char *
作为参数的函数,例如:
size_t strlen(const char *);
尽管它的参数是 const char *
,但您很有可能成功地将非常量 char
数组传递给此函数:
char buffer[256];
// Some code.
size_t l=strlen(buffer);
你关于参考文献的问题是完全一样的。可修改的左值可自动转换为对同一类型的 const 对象的引用。你不用担心,编译器会帮你完成。
还有许多其他规则。这可能是您第一次接触 C++ 的自动转换规则(或隐式转换规则)。这不会是你的最后一次。
So, what is the real difference between these two and why both of them work?
没有实际区别。两个版本之间存在一些迂腐的差异,但它们产生相同的逻辑结果。