Sdílet prostřednictvím


Ukazatelé const a volatile

Klíčová slova const a volatile mění způsob práce s ukazateli.Klíčové slovo const určuje, že ukazatel po inicializaci nelze upravit. Ukazatel je po inicializaci chráněn před úpravami.

Klíčové slovo volatile určuje, že hodnotu přiřazenou k následujícímu názvu lze upravit akcemi i mimo aplikaci uživatele.Klíčové slovo volatile je proto užitečné k deklaraci objektů ve sdílené paměti, ke kterým může přistoupit několik procesů nebo oblastí globálních dat používaných pro komunikaci s rutinami služby přerušení.

Je-li název deklarován jako volatile, kompilátor jeho hodnotu znovu načte z paměti pokaždé, kdy k němu program přistoupí.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 nějž ukazuje ukazatel, jako const nebo volatile, použijte deklaraci v následujícím tvaru:

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 následujícího tvaru:

char * const pchc;
char * volatile pchv;

Jazyk C++ znemožňuje přiřazení, která by umožnila úpravu 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.Považte následující deklarace:

const char cch = 'A';
char ch = 'B';

Jsou-li dány předchozí deklarace dvou objektů (cch typu const char a ch typu char), jsou následující deklarace či inicializace platné:

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í nějž lze upravit konstantní objekt, a proto není povolena.Deklarace proměnné pch3 určuje, že je konstantní ukazatel (pointer), nikoli objekt. Deklarace není povolena ze stejného důvodu, z jakého není povolena deklarace proměnné pch2.

Následujících osm přiřazení ukazují 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 kombinace modifikátorů const a volatile dodržují stejná pravidla.

Ukazatele na objekty const se často používají v deklaracích 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 typu ukazatele na typ char.Jelikož jsou argumenty předávány referencí, nikoli hodnotou, funkce by mohla libovolně měnit parametry strDestination a strSource, pokud by parametr strSource nebyl deklarován jako const.Deklarace parametru strSource jako const volajícímu zajišťuje, že parametr strSource nelze volanou funkcí změnit.

[!POZNÁMKA]

Vzhledem k tomu, že dochází ke standardnímu převodu z typu název_typu * na typ const název_typu *, lze funkci strcpy_s předat argument typu char *.Naopak to však neplatí. Neexistuje žádný implicitní převod, který by z objektu nebo ukazatele odstranil atribut const.

Ukazatel s atributem const daného typu lze přiřadit ukazateli stejného typu.Ukazatel, který atribut const nemá, však nelze přiřadit do ukazatele s atributem 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é

Referenční dokumentace

Ukazatelé