在C++中从const成员函数修改引用成员

31

我正在处理代码的const正确性,并想知道为什么这段代码可以编译:

class X
{
    int x;
    int& y;
public:
    X(int& _y):y(_y)
    {
    }
void f(int& newY) const
    {
        //x = 3; would not work, that's fine
        y = newY; //does compile. Why?
    }
};

int main(int argc, char **argv) 
{
    int i1=0, i2=0;
    X myX(i1);
    myX.f(i2);
...
}

据我所知,函数f()修改了对象myX,尽管它标记为const。我怎样才能确保当我对y进行赋值时编译器发出警告?(Visual C++ 2008)

非常感谢!


3
如果将它作为指针而不是引用来考虑,你会发现*y = newY依旧可以是const的,因为指针本身并没有被改变,只有指向的对象发生了变化。同样地,引用本身是无法改变的,只有其所指向的对象可以改变。 - GManNickG
3个回答

30

因为您没有改变X中的任何变量。 实际上,您正在更改相对于您的类是外部人物的_y。 别忘了:

y = newY;

newY的值分配给由y指向的变量,但不是引用本身。只有在初始化时才考虑引用。


10
+1,这就是答案。注意与指针的等价性,或许更容易理解。假设你声明了int *y;,那么*y = newY是有效的,但y = &newY则无效。 - falstro
谢谢。我认为我真正想要的是将指针作为成员。 - Philipp
4
当然,y可以被改为指向一个类成员,这样它就会修改类的状态。在这个例子中恰巧没有这样做。 - visitor
@visitor:我的第一反应也是这样。但那会很恶劣。 - Claudiu

8

这种情况类似于指针成员。在 const 成员函数中,const 应用于指针本身,而不是指向的对象。

这就是以下代码的区别:

X* const //this is how the const applies: you can modify the pointee
const X*

除了X& const不是有效的语法,因为引用不能首先指向另一个对象(它们默认始终是const)。总之:方法上的const对成员引用没有影响。

2

作为接受答案的额外信息,我想说,实际上可以更改X中的变量。

因为您没有更改X中的任何变量。

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Bar {
public:
    void funcA() const {
        c++;
    }

    int b = 3;
    int &c = b;
};

int main()
{
    Bar b;
    b.funcA();
    cout << b.b << endl;  //4
}

因此,这个问题的主要思想是:

它修改成员所引用的内容,而不是修改成员本身。

这也适用于指针成员。

请参见:为什么可以通过const成员函数修改引用成员?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接