指针和引用作为const对象的成员变量

时间:2014-02-14 19:24:34

标签: c++ const

以下代码编译正常。但我不知道它是否是合法的C ++。更具体一点,如果我有一个const对象,我是否可以通过该对象的指针/引用修改变量?

class Foo {
public:
    int* a;
    int& b;
    Foo(int* _a, int& _b) : a(_a), b(_b) {}
};

int main ( int argc, char* argv[] ) {
    int x = 7;
    const Foo bar(&x, x);

    *bar.a = 3; //Leagal?
    bar.b = 7; //Legal?
    return 0;
}

2 个答案:

答案 0 :(得分:6)

这是合法的,因为类的常量意味着类成员是常量。 a是一个指针,因此指针指向的地址是常量,但存储在该地址的值不一定是。

因此bar.a实际上是int * const,而不是int const *

因为,在初始化之后,无论如何都不能引用引用另一个实体,bar.b无论bar是否被声明为const都无关紧要。

指针的常量变量是常量指针,而不是指向常量的指针。引用的常量变量是引用,而不是对常量的引用。

小题外话:关于const-ness,你应该小心引用作为成员,因为以下内容可能会编译

struct Y { int m_a; };
struct X {
   const Y & m_y;
   X (const Y & y) : m_y (y) { }
};

Y y;
y.m_a = 1;
X x (y); // or const X x (y) -- does not matter
// X.m_y.m_a == 1

y.m_a = 2;
// now X.m_y.m_a == 2, although X.m_y is supposed to be const

由于可以将指向非const的指针分配给指向const的指针,因此可以使用指针构建一个类似的示例。请记住,const仅保证您不会通过此变量修改变量,它不能保证变量的内容根本不会被修改。

答案 1 :(得分:3)

我发现在C ++中考虑const的最佳方法是保护对象的物理位。它对它所引用的对象没有真正的保护。您可以使用const方法控制对象定义,以提供更深层次的值保护,但默认情况下,C ++实际上只保护物理对象本身

C ++允许您通过const值修改指针内容的原因之一是它真的无法阻止您。想象一下,C ++不允许该特定结构。通过执行以下操作,您可以轻而易举地违反它

size_t t1 = (size_t)bar.a; // legal 
int* t2 = (int*)t1;        // legal 
*t2 = 3;                   // exactly the same as *bar.a = 3