Почему С++ не принуждает const к данным указателя?

Возможный дубликат:
Почему спецификатор const не работает над элементами указателя на объектах const?

Рассмотрим следующий класс, который имеет указательный элемент int *a. Метод const constMod разрешен компилятором, даже если он изменяет данные указателя. Почему компилятор не создает данные указателя const в контексте метода const? Если a был просто int, нам не разрешили бы его модифицировать в методе const.

class ConstTest
{
    public:

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

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

    int *a;
};

Я использую g++ в linux.

Ответ 1

Это просто проблема с владением... нет способа, которым компилятор может знать, является ли объект, указывающий на объект, логически частью объекта или нет, поэтому он оставил программисту возможность защищать такие проблемы. const членам разрешено выполнять операции с побочными эффектами, если они не изменяют свою собственную кажущуюся ценность. Это ничем не отличается от того, чтобы позволить им называть say std::cout::operator<<() или какую-либо другую неконстантную функцию....

Ответ 2

Внутри constMod() объявление a рассматривается как:

int *const a;

что означает, что указатель имеет постоянное значение, а не то, на что он указывает. Похоже, вы ожидаете, что это будет рассматриваться как:

const int *a;

который отличается.

Ответ 3

Сам указатель не изменяется, а только указанные данные. Даже если это звучит странно с человеческой точки зрения, с точки зрения компилятора, ни один из членов класса не изменяется.

Ответ 4

Что такое const в приведенном выше случае, это сам указатель. Вам не разрешено делать ++a;. Однако это не мешает вам изменять данные, на которые указывают.

Ответ 5

Я считаю, потому что здесь вы пытаетесь изменить значение, на которое указывает datamember. Если вы попытаетесь изменить элемент данных, это будет ошибка.

Смысл, вы получите ошибку, если вы добавите что-то другое вместо изменения значения

Ответ 6

const Функции-члены не позволят вам изменять его.

В вашем примере у вас есть указатель, который указывает int.

И в методе const вы изменяете значение, на которое оно указывает, но не самый указатель.

Попробуйте дать ++a, который фактически изменит значение указателя и не будет разрешен в вашем методе const.

Ответ 7

Рассмотрим

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 int immutable_data[120]
const int* mutable_view = immutable_data;
for(const int* end = immutable_data + 120; mutable_view != end; ++mutable_view) {
  // can't modify *mutable_view
}

Это потому, что указатели не всегда имеют право собственности. В некоторых случаях указатели представляют собой вид объекта (первый пример) или итераторы в необработанный массив (второй пример). В этих случаях нет смысла ограничивать операции, доступные для указателей, только потому, что указанные данные являются неизменяемыми (или считаются неизменными).

Первый пример - немного надуманный, но допустимая его версия - это когда вы используете элемент-указатель для реализации ассоциации объектов, и вы не хотите, чтобы проблема с ссылочным элементом. Иногда типами указаний являются const.