Z mojego punktu widzenia const
modyfikatory należy czytać od prawej do lewej. Z tego wynika, że:
const char*
jest wskaźnikiem, którego elementy char nie mogą być modyfikowane, ale sam wskaźnik może, a
char const*
jest stałym wskaźnikiem do mutable
znaków.
Ale otrzymuję następujące błędy dla następującego kodu:
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
Więc ... który to jest? Czy moje rozumienie lub kompilator (VS 2005) są błędne?
Odpowiedzi:
Właściwie zgodnie ze standardem
const
modyfikuje element bezpośrednio po jego lewej stronie . Użycieconst
na początku deklaracji jest po prostu wygodnym skrótem myślowym. Zatem następujące dwie instrukcje są równoważne:char const * pointerToConstantContent1; const char * pointerToConstantContent2;
Aby zapewnić, że sam wskaźnik nie zostanie zmodyfikowany,
const
należy umieścić go po gwiazdce:char * const constantPointerToMutableContent;
Aby chronić zarówno wskaźnik, jak i zawartość, na którą wskazuje, użyj dwóch stałych.
char const * const constantPointerToConstantContent;
Osobiście przyjąłem zawsze umieszczanie stałej po części, której nie zamierzam modyfikować, w taki sposób, aby zachować spójność, nawet gdy wskaźnik jest częścią, którą chcę zachować na stałym poziomie.
źródło
Działa, ponieważ oba są takie same. Możesz być w tym zdezorientowany,
const char* // both are same char const*
i
char* const // unmutable pointer to "char"
i
const char* const // unmutable pointer to "const char"
[Aby to zapamiętać, oto prosta reguła: „*” wpływa najpierw na cały jego LHS ]
źródło
unmutable pointer to char*
Jest to niezmienny wskaźnik wskazujący nachar
niechar *
.Dzieje się tak, ponieważ zasada brzmi:
ZASADA:
const
wiąże w lewo, chyba że nic nie ma po lewej stronie, wtedy wiąże się z prawej :)więc spójrz na te jako:
(const --->> char)* (char <<--- const)*
oba takie same! och, i
--->>
i<<---
NIE są operatorami, po prostu pokazują, do czego sąconst
przypisane.źródło
-->>
i działa tylko na wartościach. Spróbujint i = 8; std::cout << (i -->> 1) << std::endl;
:)(z 2 prostych pytań inicjalizacyjnych zmiennych )
Naprawdę dobra zasada dotycząca
const
:(zobacz Vandevoorde / Josutiss „Szablony C ++: kompletny przewodnik”)
Na przykład:
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.
Odkąd stosuję się do tej praktycznej zasady, nigdy więcej nie zinterpretowałem błędnie takich deklaracji.
(: sisab retcarahc-rep a no ton, sisab nekot-rep a no tfel-ot-thgir naem I hguohT: tidE
źródło
const char* const
i dzięki tobie teraz to rozumiem.Oto jak zawsze staram się interpretować:
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`".
Mam nadzieję, że to pomoże!
źródło
W obu przypadkach wskazujesz na stały znak.
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?
Domyślnie
const
ma zastosowanie do tego, co znajduje się bezpośrednio po lewej stronie, ale może mieć zastosowanie do tego, co znajduje się bezpośrednio po jego prawej stronie, jeśli nic go nie poprzedza, jak w (1).źródło