Const char * и char const * - они одинаковы?

По моему мнению, модификаторы const должны читаться справа налево. Из этого я получаю следующее:

const char*

- это указатель, элементы которого char не могут быть изменены, но сам указатель может и

char const*

- постоянный указатель на символы mutable.

Но я получаю следующие ошибки для следующего кода:

const char* x = new char[20];
x = new char[30];   //this works, as expected
x[0] = 'a';         //gives an error as expected

char const* y = new char[20];
y = new char[20];   //this works, although the pointer should be const (right?)
y[0] = 'a';         //this doesn't although I expect it to work

Итак... кто это? Неправильно ли мое понимание или мой компилятор (VS 2005)?

Ответ 1

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

char const * pointerToConstantContent1;
const char * pointerToConstantContent2;

Чтобы убедиться, что сам указатель не изменен, после звездочки следует поместить const:

char * const constantPointerToMutableContent;

Чтобы защитить как указатель, так и контент, на который он указывает, используйте две константы.

char const * const constantPointerToConstantContent;

Я лично всегда принимал константу после той части, которую я намереваюсь не изменять, чтобы поддерживать согласованность, даже если указатель является частью, которую я хочу сохранить постоянной.

Ответ 2

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

const char*  // both are same
char const*

и

char* const  // unmutable pointer to "char"

и

const char* const  // unmutable pointer to "const char"

[Чтобы помнить об этом, вот простое правило: '*' сначала влияет на все его LHS)

Ответ 3

Это потому, что правило:

ПРАВИЛО: const связывается влево, если ничего не осталось слева, затем он привязывается справа:)

так, посмотрите на них как:

(const --->> char)*
(char <<--- const)*

оба одинаковые! oh и --->> и <<--- НЕ являются операторами, они просто показывают, к чему привязывается const.

Ответ 4

(from 2 вопроса об инициализации простой переменной)

Действительно хорошее эмпирическое правило относительно const:

Чтение деклараций справа налево.

(см. Vandevoorde/Josutiss "С++ Templates: The Complete Guide" )

Например:

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

С тех пор, как я следую этому правилу большого пальца, я никогда не неправильно истолковал такие объявления.

(: sisab retcarahc-rep a no ton, sisab nekot-rep a no tfel-ot-thgir naem я hguohT: tidE

Ответ 5

Вот как я всегда стараюсь интерпретировать:

char *p

     |_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".

char * const p

     |_____ again start from the asterisk. "content of constant (since we have the `const` 
            modifier in the front) `p` is a `char`".

char const *p

           |_____ again start from the asterisk. "content of `p` is a constant `char`".

Надеюсь, что это поможет!

Ответ 6

В обоих случаях вы указываете на константу char.

const char * x  //(1) a variable pointer to a constant char
char const * x  //(2) a variable pointer to a constant char
char * const x  //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?

По умолчанию, const применяется к тому, что находится непосредственно в левой части, но может применяться к тому, что сразу же справа, если ничего не предшествует ему, как в (1).