以下代码编译正常。但我不知道它是否是合法的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;
}
答案 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