const a volatile – ukazatele
Klíčová slova const a volatile mění způsob zacházení s ukazateli. Klíčové const
slovo určuje, že ukazatel nelze po inicializaci změnit; ukazatel je chráněn před úpravami od té doby.
Klíčové volatile
slovo určuje, že hodnota přidružená k názvu, který následuje, lze upravit jinými akcemi než akcemi v uživatelské aplikaci. volatile
Klíčové slovo je proto užitečné pro deklarování objektů ve sdílené paměti, ke kterým může přistupovat více procesů nebo globálních datových oblastí používaných pro komunikaci s přerušovanými rutinami služby.
Když je název deklarován jako volatile
, kompilátor znovu načte hodnotu z paměti při každém přístupu k programu. Tím jsou výrazně omezeny možné optimalizace. Pokud však může dojít k nečekané změně stavu objektu, jde o jediný způsob, jak lze zajistit předvídatelný výkon programu.
Chcete-li deklarovat objekt, na který odkazuje ukazatel jako const
nebo volatile
, použijte deklaraci formuláře:
const char *cpch;
volatile char *vpch;
Chcete-li deklarovat hodnotu ukazatele – tedy skutečnou adresu uloženou v ukazateli – jako const
nebo volatile
, použijte deklaraci formuláře:
char * const pchc;
char * volatile pchv;
Jazyk C++ zabraňuje přiřazením, která by umožňovala úpravy objektu nebo ukazatele deklarovaného jako const
. Taková přiřazení by odstranila informaci, s níž byl objekt nebo ukazatel deklarován, a porušila by tak záměr původní deklarace. Vezměte v úvahu následující deklarace:
const char cch = 'A';
char ch = 'B';
Vzhledem k předchozím deklaracím dvou objektů (cch
znak typu ach
znak typu) jsou platné následující deklarace/inicializace:
const char *pch1 = &cch;
const char *const pch4 = &cch;
const char *pch5 = &ch;
char *pch6 = &ch;
char *const pch7 = &ch;
const char *const pch8 = &ch;
Následující deklarace či inicializace jsou chybné.
char *pch2 = &cch; // Error
char *const pch3 = &cch; // Error
Deklarace proměnné pch2
deklaruje ukazatel, pomocí kterého lze upravit konstantní objekt, a proto není povolena. pch3
Deklarace určuje, že ukazatel je konstantní, nikoli objekt; deklarace je zakázána pro stejný důvod, pch2
proč je deklarace zakázána.
Následujících osm přiřazení ukazuje přiřazování pomocí ukazatele a změnu hodnoty ukazatele z předchozích deklarací. Pro tuto chvíli předpokládejme, že pro proměnné pch1
až pch8
byla inicializace správná.
*pch1 = 'A'; // Error: object declared const
pch1 = &ch; // OK: pointer not declared const
*pch2 = 'A'; // OK: normal pointer
pch2 = &ch; // OK: normal pointer
*pch3 = 'A'; // OK: object not declared const
pch3 = &ch; // Error: pointer declared const
*pch4 = 'A'; // Error: object declared const
pch4 = &ch; // Error: pointer declared const
Ukazatele deklarované jako volatile
, nebo jako směs const
a volatile
, dodržují stejná pravidla.
Ukazatele na const
objekty se často používají v deklarací funkcí následujícím způsobem:
errno_t strcpy_s( char *strDestination, size_t numberOfElements, const char *strSource );
Předchozí příkaz deklaruje funkci, strcpy_s, kde dva ze tří argumentů jsou ukazatelem typu na char
. Vzhledem k tomu, že argumenty jsou předány odkazem, a ne hodnotou, funkce by byla volná k úpravě obou strDestination
a strSource
pokud strSource
by nebyla deklarována jako const
. strSource
const
Deklarace ujišťuje volajícího, že strSource
volanou funkci nelze změnit.
Poznámka
Vzhledem k tomu, že existuje standardní převod z typename* naconst
typename*, je legální předat argument typu char *
strcpy_s. Opak však není pravdivý; Neexistuje žádný implicitní převod pro odebrání const
atributu z objektu nebo ukazatele.
const
Ukazatel daného typu lze přiřadit ukazateli stejného typu. Ukazatel, který však nelze const
přiřadit k ukazateli const
. Následující kód ukazuje správná i nesprávná přiřazení:
// const_pointer.cpp
int *const cpObject = 0;
int *pObject;
int main() {
pObject = cpObject;
cpObject = pObject; // C3892
}
Následující příklad ukazuje, jak deklarovat objekt jako const, pracujete-li s ukazatelem na ukazatel na objekt.
// const_pointer2.cpp
struct X {
X(int i) : m_i(i) { }
int m_i;
};
int main() {
// correct
const X cx(10);
const X * pcx = &cx;
const X ** ppcx = &pcx;
// also correct
X const cx2(20);
X const * pcx2 = &cx2;
X const ** ppcx2 = &pcx2;
}
Viz také
Váš názor
https://aka.ms/ContentUserFeedback.
Připravujeme: V průběhu roku 2024 budeme postupně vyřazovat problémy z GitHub coby mechanismus zpětné vazby pro obsah a nahrazovat ho novým systémem zpětné vazby. Další informace naleznete v tématu:Odeslat a zobrazit názory pro