Почему в C ++ разрешено изменять память переменной члена-указателя постоянного объекта извне?

Я пытался понять, когда я пишу функцию в C ++ с постоянным аргументом и переменной указателя внутри этого объекта, чем флаг const не защищает основную память от изменений.
Например, совершенно законно делать следующее в operator=() функция класса называется X:

class X
{
public:
X& operator=(const X& other)
{
this->data = other.data; //(*)
return *this;
}

private:
int* data;
};

(*): Это то же самое, что и следующее:

int* some_pointer;
int* const other_pointer = some_pointer;
int* class_pointer = other_pointer;

Но не так, как:

const int* other_pointer;
int* class_pointer = other_pointer;

Что приведет к следующей ошибке:

error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
int* class_pointer = other_pointer;
^

Я понимаю почему other.x приводится к int* const но я не понимаю, почему это не приводится к const* int в то же время (что является const int* const). Когда я пишу функцию с const Аргумент Моя логика предполагает, что что-то внутри этого аргумента должно наследовать постоянство, потому что это должно быть целью const, чтобы защитить базовые данные от модификации.

Когда к элементу указателя обращаются извне const версия класса, я думаю, это должно быть разумным ожиданием того, что объект const Ключевое слово должно защищать все (даже память), которая выходит из класса от модификации. Аргумент против этого заключается в том, что внешняя память не принадлежит объекту, поэтому не стоит также защищать его. Моя точка зрения на это заключается в том, что в этом случае (из любых других случаев, когда к нему обращаются где-то еще с любыми правами доступа), мы берем что-то из const объект. Другими словами, это дает видимость чему-то вне себя. Так в чем же причина не делать видимость const? Это не изменило бы права доступа к памяти в любом другом месте кода!

6

Решение

«Когда я пишу функцию с аргументом const, моя логика предполагает, что что-то внутри этого аргумента должно наследовать constness, потому что это должно быть целью const, чтобы защитить базовые данные от модификации».

Вы совершенно правы в этом, однако указатель хранится внутри X-объекты вне предмет. Снаружи не влияет Xконстантность, просто данные хранятся внутри X,

5

Другие решения

Почему вы думаете, что, поскольку указатель является постоянным, то, на что указывает указатель, должно быть постоянным? Это не обязательно следует.

Иногда вам нужен указатель, который всегда должен указывать на определенное место, но с помощью которого вы можете изменить указанное место. Там нет ничего о class X что говорит о том, что вы не сможете изменить память data указывает на.

Что еще более важно, вы неправильно думаете о ключевом слове const. Дано

X& operator=(const X& other)

все, что вы делаете, это сообщаете компилятору, что вы не собираетесь менять other внутри operator=() и попросить компилятор помешать вам сделать это на случай, если вы забудете. Ни больше ни меньше. Это ничего не говорит о постоянстве other вне operator=() ни о постоянстве чего-либо, ни указателя внутри other указывает на.

1

int* const other_pointer
declare other_pointer as const pointer to int

в отличие от:

const int* other_pointer
declare other_pointer as pointer to const int

любезно предоставлено http://cdecl.org/

Обратите внимание на разницу в размещении конст.

0

Вы не меняете значение other.dataтак что нет const нарушение. Вы могли бы, конечно, изменить объект, который other.data указывает на то, что компилятор не несет ответственности за соблюдение const-правильности.

0
По вопросам рекламы [email protected]