在C++中:常量引用意味着"read-only view of"还是需要被引用对象的不可变性?

in C++: Is const reference means "read-only view of" or it requires immutability of object being referenced?

本文关键字:引用 对象 不可变 可变性 of C++ 常量 意味着 view read-only      更新时间:2023-10-16

这个问题可以通过下面的例子来表述:这段代码有效吗?

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?例如,如果类型Xbool,则按值存储x比按引用存储提供更好的性能和更少的内存消耗。

换句话说:如果随后对myObj的方法的调用修改了myObj内部相应的内部值,那么局部变量x是否保证会跟踪该内部值的变化?

这是有效的代码,因为a不是constconst引用意味着您不能通过引用修改被引用到的对象。

在这种特殊情况下,您所要做的只是创建一个REFERENCE,即const,这意味着ca不能修改它所引用的值(在这种情况下为a(。

一个常见的用法是将常量引用传递给函数:

void foo(const int& cr)
{
   ... use cr ... 
}

这表明尽管该值是一个参考,但函数foo不会改变cr中的值。用一个可修改的int变量,甚至是不能被引用的东西来调用这个函数是完全有效的(例如foo(4);——值4只是一个常量,所以不能真正用作引用——编译器会通过创建一个临时int变量来"修复"这个问题,并将引用传递给它(。

当然,这更常用于比int更复杂的类型,例如std::stringstd::vector。这种情况下的主要原因是避免复制值,而不是"我想要一个引用"。

由于引用只是变量的另一个名称,而不是对象本身,因此在您显示的代码段中,它可以被视为只读引用。与引用一起提供的代码只能访问它,但它不能保证对象本身不会在程序的其他位置更改。