2013-03-05 2 views
2

В книге я читал о C++ (C++ для чайников) есть раздел, в котором говорится следующее:C++ указатель на постоянную ошибку

int nVar = 10; 
int* pVar = &nVar; 
const int* pcVar = pVar; // this is legal 
int* pVar2 = pcVar;  // this is not 

Книга затем продолжает объяснять:

The assignment pcVar = pVar; is okay -- this is adding the const restriction. The final assignment in the snippet is not allowed since it attempts to remove the const-ness of pcVar

Мой вопрос: почему последняя строка не является «законной». Я не понимаю, как это мешает «constness» pcVar. Благодарю.

+1

'int pVar = & nVar' не является законным - вы преобразовываете целое число в указатель на целое число. Я подозреваю, что это опечатка, но вы можете не исправить ее. –

+0

В этом коде нет назначений, и любая книга, которая ссылается на эти инициализации как таковые, не должна быть пригодной для чтения. – chris

+0

На самом деле это так в книге. Я не знаю, является ли это опечаткой, но вопрос все еще имеет смысл, если я должен это исправить? – Iowa15

ответ

3
const int *pcVar = pVar; 
int *pVar2 = pcVar; 

Если pcVar является const int *, что означает, что int он указывает, может быть const. (Это не в этом случае, но это может быть.) Поэтому, если вы назначаете pVar2, который является неконстантным int *, он по-прежнему позволяет указать int для его изменения.

Так что если pcVarфактически указал на const int, и назначить int * по его адресу, то, что int * указатель (pVar2 в данном случае) позволит вам, разыменовывая, чтобы изменить его, и это незаконно (это нарушение ограничения, поэтому оно вызывает неопределенное поведение).

1

Смешивание const и non-const запрещено. Причина в том, что если вы сообщите компилятору, что значение одного места является константой, а затем использовать другой указатель для изменения этого значения, вы нарушили контракт const, который вы сделали с первым элементом.

+0

Хорошо, что делает смысл – Iowa15

2

Это просто говорит, что вы не можете создать указатель не const от const (по крайней мере, не без const_cast).

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

void function(int* m) { 
    *m = 20; 
} 

int main() { 
    const int x = 10; 
    //Oops! x isn't constant inside function any more, and is now 20! 
    function(&x); 
} 

Кроме того, пожалуйста, ознакомьтесь с The Definitive C++ Book and Guide List, он имеет много больших ссылок (C++ для чайников не совсем делают порез).

1

pcVar остается неизменным, но pVar2 указывает на не const, const может быть добавлен, но не удален. Компилятор не смотрит на исходный nVar, не являющийся константой, а только на попытку назначить const не const. В противном случае вы можете обойти const и изменить значение.

+0

Это имеет смысл – Iowa15

2

Все компилятор знает, что pcVar является const int*. То есть, это указывает на const int. Просто потому, что вы указали на не constint не имеет значения. Для всего компилятора значение указателя могло бы измениться в какой-то момент, чтобы указать на действительно constint. Поэтому компилятор не позволит вам конвертировать из const int* обратно в int*, потому что он будет лежать около const неизвестного объекта, на который он указывал.

Для более простого примера рассмотрим:

const int x; 
const int* pc = x; 
int* p = pc; // Illegal 

Здесь x действительно является const int. Если вы можете сделать эту третью строку, вы можете получить доступ к объекту const int через p (выполнив *pc) и изменив его. Это было бы плохо - x - const по причине.

Однако, в данном примере вы дали, так как вы знаете , что исходный объект был не- const, вы могли бы использовать const_cast, чтобы заставить компилятор в доверяя вам:

int* pVar2 = const_cast<int*>(pcVar); 

Обратите внимание, что это только действителен, если вы знаете наверняка, что объект не является const.

1
int * pVar = &nVar; 
*pVar = 4 //is legal 

const int* pcVar = pVar; // this is legal 
*pcVar = 3 // this is not legal, we said the value was const thus it can not be changed 

int* pVar2 = pcVar;  // this is not legal because... 
*pVar2 = 3 -> *pcVar = 3 
1

Вторая строка INT PVAR = &nVar; ошибка. компилятор g ++. Ошибка: неверное преобразование из 'int *' в 'int'

Смежные вопросы