C++
const trefwoord
Zoeken…
Syntaxis
- const Type myVariable = initial; // Declareert een const-variabele; kan niet veranderd worden
- const Type & myReference = myVariable; // Declareert een verwijzing naar een const-variabele
- const Type * myPointer = & myVariable; // Geeft een aanwijzer naar const aan. De aanwijzer kan veranderen, maar het onderliggende gegevenslid kan niet worden gewijzigd via de aanwijzer
- Typ * const myPointer = & myVariable; // Geeft een const-aanwijzer aan. De aanwijzer kan niet opnieuw worden toegewezen om naar iets anders te wijzen, maar het onderliggende gegevenslid kan worden gewijzigd
- const Type * const myPointer = & myVariable; // Verklaart een const pointer-naar-const.
Opmerkingen
Een variabele gemarkeerd als const
niet 1 worden veranderd. Pogingen om niet-const-bewerkingen erop aan te roepen, resulteren in een compilerfout.
1: Nou, het kan worden gewijzigd via const_cast
, maar dat moet je bijna nooit gebruiken
Const lokale variabelen
Verklaring en gebruik.
// a is const int, so it can't be changed
const int a = 15;
a = 12; // Error: can't assign new value to const variable
a += 1; // Error: can't assign new value to const variable
Binden van referenties en verwijzingen
int &b = a; // Error: can't bind non-const reference to const variable
const int &c = a; // OK; c is a const reference
int *d = &a; // Error: can't bind pointer-to-non-const to const variable
const int *e = &a // OK; e is a pointer-to-const
int f = 0;
e = &f; // OK; e is a non-const pointer-to-const,
// which means that it can be rebound to new int* or const int*
*e = 1 // Error: e is a pointer-to-const which means that
// the value it points to can't be changed through dereferencing e
int *g = &f;
*g = 1; // OK; this value still can be changed through dereferencing
// a pointer-not-to-const
Const wijst
int a = 0, b = 2;
const int* pA = &a; // pointer-to-const. `a` can't be changed through this
int* const pB = &a; // const pointer. `a` can be changed, but this pointer can't.
const int* const pC = &a; // const pointer-to-const.
//Error: Cannot assign to a const reference
*pA = b;
pA = &b;
*pB = b;
//Error: Cannot assign to const pointer
pB = &b;
//Error: Cannot assign to a const reference
*pC = b;
//Error: Cannot assign to const pointer
pC = &b;
Const-lidfuncties
Lidfuncties van een klasse kunnen const
worden verklaard, wat de compiler en toekomstige lezers vertelt dat deze functie het object niet zal wijzigen:
class MyClass
{
private:
int myInt_;
public:
int myInt() const { return myInt_; }
void setMyInt(int myInt) { myInt_ = myInt; }
};
In een const
-functie is this
aanwijzer feitelijk een const MyClass *
plaats van een MyClass *
. Dit betekent dat u geen lidvariabelen binnen de functie kunt wijzigen; de compiler geeft een waarschuwing. Dus setMyInt
kon niet const
worden verklaard.
U moet de ledenfuncties bijna altijd als const
markeren wanneer mogelijk. Alleen const
lid functies kunnen worden opgeroepen op een const MyClass
.
static
methoden kunnen niet worden verklaard als const
. Dit komt omdat een statische methode tot een klasse behoort en niet op object wordt aangeroepen; daarom kan het nooit de interne variabelen van het object wijzigen. Dus het verklaren van static
methoden als const
zou overbodig zijn.
Vermijden van dubbele code in const- en niet-const-gettermethoden.
In C ++ kunnen methoden die alleen verschillen per const
kwalificatie worden overbelast. Soms is er behoefte aan twee versies van getter die een verwijzing naar een lid retourneren.
Laat Foo
een klasse zijn, die twee methoden heeft die identieke bewerkingen uitvoeren en een verwijzing retourneert naar een object van het type Bar
:
class Foo
{
public:
Bar& GetBar(/* some arguments */)
{
/* some calculations */
return bar;
}
const Bar& GetBar(/* some arguments */) const
{
/* some calculations */
return bar;
}
// ...
};
Het enige verschil tussen hen is dat een methode niet-const is en een niet-const-verwijzing retourneert (die kan worden gebruikt om een object te wijzigen) en de tweede is const en geeft const-verwijzing terug.
Om codeduplicatie te voorkomen, is er de verleiding om de ene methode van de andere te gebruiken. We kunnen de niet-const-methode echter niet vanuit de const-methode oproepen. Maar we kunnen const-methode aanroepen vanuit niet-const-one. Dat vereist dat je 'const_cast' gebruikt om de const qualifier te verwijderen.
De oplossing is:
struct Foo
{
Bar& GetBar(/*arguments*/)
{
return const_cast<Bar&>(const_cast<const Foo*>(this)->GetBar(/*arguments*/));
}
const Bar& GetBar(/*arguments*/) const
{
/* some calculations */
return foo;
}
};
In de bovenstaande code roepen we const-versie van GetBar
vanuit de niet-const GetBar
door dit naar const type te const_cast<const Foo*>(this)
: const_cast<const Foo*>(this)
. Omdat we de const-methode vanuit niet-const aanroepen, is het object zelf niet-const en is het wegwerpen van de const toegestaan.
Bekijk het volgende meer complete voorbeeld:
#include <iostream>
class Student
{
public:
char& GetScore(bool midterm)
{
return const_cast<char&>(const_cast<const Student*>(this)->GetScore(midterm));
}
const char& GetScore(bool midterm) const
{
if (midterm)
{
return midtermScore;
}
else
{
return finalScore;
}
}
private:
char midtermScore;
char finalScore;
};
int main()
{
// non-const object
Student a;
// We can assign to the reference. Non-const version of GetScore is called
a.GetScore(true) = 'B';
a.GetScore(false) = 'A';
// const object
const Student b(a);
// We still can call GetScore method of const object,
// because we have overloaded const version of GetScore
std::cout << b.GetScore(true) << b.GetScore(false) << '\n';
}