C++ 为什么';tc++;对指针数据强制常量?

C++ 为什么';tc++;对指针数据强制常量?,c++,pointers,constants,C++,Pointers,Constants,可能重复: 考虑以下具有指针成员int*a的类。编译器允许const方法constMod,即使它修改指针数据。为什么编译器不在const方法的上下文中设置指针数据const?如果a只是一个int,我们就不允许在const方法中修改它 class ConstTest { public: ConstTest(int *p): a(p) {} void constMod() const { ++(*a); } int *a; }; 我在

可能重复:

考虑以下具有指针成员
int*a
的类。编译器允许const方法
constMod
,即使它修改指针数据。为什么编译器不在const方法的上下文中设置指针数据const?如果
a
只是一个int,我们就不允许在const方法中修改它

class ConstTest
{
    public:

    ConstTest(int *p): a(p) {}

    void constMod() const {
        ++(*a);
    }

    int *a;
};
我在linux上使用g++。

constMod()
中,
a
的声明被视为:

int *const a;
const int *a;
这意味着指针有一个常量值,而不是它指向的对象。听起来您希望它被视为:

int *const a;
const int *a;

这是不同的。

指针本身没有被修改,只有指向的数据。即使从人类的角度来看,从编译器的角度来看,这听起来很奇怪,但类的任何成员都不会被更改。

这只是所有权问题。。。编译器无法知道指向的对象在逻辑上是否是该对象的一部分,因此留给程序员来监控这些问题<代码>常量成员可以执行有副作用的操作,只要他们不修改自己的表观值。这与让他们调用say
std::cout::operator没有什么区别,在上面的例子中,const是指针本身。你不允许做
++a。但是,它并不阻止您修改所指向的数据。

我相信,因为这里您试图更改datamember所指向的值。 如果试图修改数据成员,则会出现错误


也就是说,如果您指向其他对象而不是更改值,则会出现错误

const
成员函数将不允许您修改其成员

在您的示例中,有一个指向int的指针

const
方法中,修改的是指针指向的值,而不是指针本身

尝试给出,
++a
,这将实际修改指针值,并且在
常量中不允许使用。

请考虑

const T immutable_object0;
const T immutable_object1;
const T* mutable_view = ...a condition... ? &immutable_object0 : &immutable_object1;
// then later you reseat
mutable_view = ...another condition... ? &immutable_object0 : &immutable_object1;

这是因为指针并不总是拥有所有权。在某些情况下,指针是指向对象的视图(第一个示例),或者是指向原始数组的迭代器(第二个示例)。对于这些情况,仅仅因为指向的数据是不可变的(或被视为不可变的),就限制指针上可用的操作是没有意义的


第一个示例有点做作,但它的有效版本是当您使用指针成员来实现对象关联,并且您不希望遇到引用成员的麻烦时。有时指向的类型恰好是
const

,这是不是在不回答问题的情况下就不能澄清问题…?为什么?为什么不在const方法中强制const所有内容?把指针数据当作副作用似乎是很奇怪的。“马特:这就是C++的原理。假设它是一个整数而不是指针,并且您无法更改该整数。这个整数对你来说意味着什么与它的值无关。(可能是计数器、年龄等)同样,指针值与它所指向的内容无关(我们只是碰巧同意指针值始终指示地址,而不是整数等各种事物;但类比仍然成立)。对于它的价值,D语言的行为与你所期望的一样。@ Matt:扩展GMan的类比,考虑他的整数是否是数组中的索引,但是数组不属于类(也许它被传递到const函数)。即使
i
是常量,你不希望
array[i]=5
工作吗?唯一的答案是“因为它是这样的”,但我想我们大多数人都同意这通常是出乎意料的(起初),尽管后来可以找到理由,但是C++默认地提供了一个所谓的位一致性——这意味着它确保了没有一个对象的位被改变,所以它只检查指针的地址。