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).