С помощью указателя вы можете сделать две вещи.
- Вы можете изменить данные, на которые они указывают, но не могут указать на другое место в памяти.
- Вы можете указать его в другом месте памяти, но не можете изменить данные, на которые он указывает.
Теперь, когда вы говорите, int const * ptr или int const * ptr, он попадает в первую категорию. Это так же, как -
const int num = 5; // Both mean the same.
int const num = 5;
Чтобы фактически не иметь возможности перейти в другое местоположение, то есть указатель на постоянное местоположение, но иметь возможность изменять данные, семантика должна быть int* const
. Поскольку содержимое указателя является константой, оно должно быть инициализировано при объявлении.
int num = 5;
int* const ptr; // Wrong
ptr = # // Wrong
int* const ptr = #
*ptr = 100;
Однако существует третий вид. Постоянный указатель на постоянное местоположение, которое не может ни указать на другое место в памяти, ни изменять данные, на которые оно указывает. (т.е. const int * const)
А теперь , отвечая на вопросы , первые два можно скомпилировать, поскольку они не указывают на постоянные местоположения. Таким образом, они могут быть изменены на более поздних этапах.
const int const *p3 = &i1;
p3 = &i2; // Wrong
В приведенном выше фрагменте p3
- это постоянный указатель на постоянное местоположение. Таким образом, его нельзя изменить.
const
в конце функции-члена говорит, что не собирается изменять состояние объекта. Когда вы говорите *p = 1;
, вы не изменяете состояние объекта. p
по-прежнему указывает на ту же ячейку памяти. Это не разрешено делать -
int const * Coo2::getP() const
{
*p = 1; // State of `p` is still not modified.
p = new int ; // Error: Changing the memory location to which p points.
// This is what changing the state of object mean and
// is not allowed because of `const` keyword at the end of function
return this->p;
}
Надеюсь, теперь вы понимаете, почему программа компилируется:)