在C++中:常量引用意味着"read-only view of"还是需要被引用对象的不可变性?
in C++: Is const reference means "read-only view of" or it requires immutability of object being referenced?
这个问题可以通过下面的例子来表述:这段代码有效吗?
int a = 1;
const int& ca = a;
++a; //< Q: Is this valid?
cout << "a: " << a << endl;
cout << "ca: " << ca << endl; // Q: Is it guaranteed to output "2"? Is it valid at all?
对于MSVC和MinGW,上面的代码段可以按预期工作:如果我查询ca
的后记,它会返回2
(即它被非常数引用更改(。但问题是:从标准的角度来看,这种情况是如何考虑的?我们可以更改具有常量引用的对象(例如,我们必须将ca
定义为常量volatile引用才能使代码段正确(吗?
所以,若上面的代码段是正确的,那个么就意味着,const引用并不能保证被引用的对象是常量。它只禁止我们通过给定的引用来更改它,即建立引用对象的"只读"视图。这是正确的吗?
编辑:
感谢所有回答我问题的人。答案说明了这一点,这对我来说似乎很自然。然而,如果有人能参考c++标准中的特定子句,我会非常感激。
第2版:
最初的例子被扩展以使问题的概念更加清晰。
第3版
另一个例子,最初出现在我对Mats Peterson的回答的评论中。
class MyClass {
public:
// ...
const X& getX() const;
void modifyX();
private:
X m_x;
};
void someFun() {
//...
MyClass myObj = ... // non-cons
const X& x = myObj.getX();
// ...
myObj.modifyX(); // Q: is `x` guaranteed to track value of x stored in myObj here?
}
问题是:是否允许在优化期间编译以删除x
变量的更新,因为它被声明为const
?例如,如果类型X
是bool
,则按值存储x
比按引用存储提供更好的性能和更少的内存消耗。
换句话说:如果随后对myObj
的方法的调用修改了myObj
内部相应的内部值,那么局部变量x
是否保证会跟踪该内部值的变化?
这是有效的代码,因为a
不是const
。const
引用意味着您不能通过引用修改被引用到的对象。
在这种特殊情况下,您所要做的只是创建一个REFERENCE,即const
,这意味着ca
不能修改它所引用的值(在这种情况下为a
(。
一个常见的用法是将常量引用传递给函数:
void foo(const int& cr)
{
... use cr ...
}
这表明尽管该值是一个参考,但函数foo
不会改变cr
中的值。用一个可修改的int
变量,甚至是不能被引用的东西来调用这个函数是完全有效的(例如foo(4);
——值4只是一个常量,所以不能真正用作引用——编译器会通过创建一个临时int变量来"修复"这个问题,并将引用传递给它(。
当然,这更常用于比int
更复杂的类型,例如std::string
或std::vector
。这种情况下的主要原因是避免复制值,而不是"我想要一个引用"。
由于引用只是变量的另一个名称,而不是对象本身,因此在您显示的代码段中,它可以被视为只读引用。与引用一起提供的代码只能访问它,但它不能保证对象本身不会在程序的其他位置更改。
- 引用对象成员函数的成员函数
- 从 Base 引用对象调用派生类的成员
- 转换引用对象的边界框?
- 现代编译器会优化只引用对象子集的局部变量吗
- l值引用对象上的Constexpr成员函数:Clang和gcc不同意
- 将 const 类型引用对象注册为类成员对象C++
- Boost Intervocess:通过迭代通过从结构引用对象的映射进行迭代时
- 无法用2D矢量成员引用对象
- 在由引用对象传递中访问由引用对象传递的变量
- 如何使用QString引用对象名称
- 使用自动迭代器引用对象
- C++ 在另一个对象中引用对象的当前状态
- 使用共享对象和引用对象进行引用计数
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- 引用对象的动态类型何时可以更改
- 引用对象内部的指针
- C++从全局静态函数中引用对象
- C++如何仅在没有其他人直接或间接引用对象指针时删除该指针
- 如何使用C++引用对象
- 为什么引用对象仅保存特定类型的引用