提问人:ConventionalProgrammer 提问时间:3/16/2023 最后编辑:Vlad from MoscowConventionalProgrammer 更新时间:3/16/2023 访问量:86
非常量对象作为具有常量参数的函数的参数 (C++)
Non-constant object as an argument to a function with constant parameter (C++)
问:
当我在函数中创建一个局部变量并将此变量传递到需要引用常量整数的函数中时,程序工作正常:num
main()
dosmth(const int& num)
#include <iostream>
using namespace std;
void dosmth(const int& num) { // Same address. Non-modifiable.
cout << &num << endl;
// num++; // Compiler error
}
int main() {
int num = 10; // Same adress. Modifiable.
dosmth(num);
num++; // No compiler error.
cout<<#
return 0;
}
当前的 ISO C++ (2020) 标准在第 9.4.3 节中指出:
...... 对类型“cv1 T1”的引用由 type “cv2 T2”如下:
如果引用是左值引用和初始值设定项表达式 是一个左值(但不是位域),而“cv1 T1”是 与“cv2 T2”兼容的参考,
或具有类类型(即 T2 是类类型),其中 T1 与 T2 无关,可以转换为类型的左值 “cv3 T3”,其中“cv1 T1”与“cv3 T3”(此 通过枚举适用的转换来选择转换 函数 (12.4.1.6) 并通过重载选择最佳函数 第(12.4)号决议)。
然后,引用绑定到 Initializer 表达式 Lvalue 第一种情况和左值转换的结果在 第二种情况(或者,在任一情况下,到相应的基类 对象的子对象) .........
换言之,引用绑定到初始值设定项表达式 lvalue(在本例中为 a)。但是,我无法理解函数中本地声明的变量(即)如何由两个函数(和)共享并同时占据相同的虚拟地址,而其类型在这两个函数的范围内不同(一个是只读的,另一个不是)。据我所知,按引用传递会为实际参数创建一个别名,该别名不是副本,而是实际指向实际变量。如果引用根据标准绑定到 a,它现在应该指向 ,但它指向的是一个变量,即 。const int
main
int
main
dosmth
const int
const int
num
答:
您声明了一个非常量对象
int num = 10; // Same adress. Modifiable.
所以它可能会被改变。
num++; // No compiler error.
通过常量引用将对象传递给函数。因此,在函数中,对象可能不会被更改。
来自 C++ 20 标准(9.2.9.2 cv 限定符)
3 指向 cv 限定类型的指针或引用实际上不需要 指向或引用 CV 限定的对象,但将其视为 确实;const 限定的访问路径不能用于修改对象 即使引用的对象是非常量对象,并且可以是 通过其他访问路径进行修改。
例如,您可以编写
int x = 10;
const int &crx = x;
int &rx = x;
然后
rx += 20;
但你不能写
crx += 20;
评论
下一个:函数调用中的堆栈分配
评论
const ref&
ref
const ref&
int a = 0;
const int& b = a;
num
const int
const int
int
const
const
const
num
num