Sdílet prostřednictvím


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ů (cchznak 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é pch1pch8 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. strSourceconst 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é

Ukazatele nezpracovanéukazatele