C++
const nyckelord
Sök…
Syntax
- const Skriv myVariable = initial; // Förklarar en const-variabel; kan inte ändras
- const Type & myReference = myVariable; // Förklarar en hänvisning till en konst-variabel
- const Skriv * myPointer = & myVariable; // Förklarar en pekare till konst. Pekaren kan ändras, men den underliggande dataleden kan inte ändras genom pekaren
- Skriv * const myPointer = & myVariable; // Förklarar en konstpekare. Pekaren kan inte tilldelas för att peka på något annat, men den underliggande dataleden kan ändras
- const Type * const myPointer = & myVariable; // Förklarar en konstpekare till konst.
Anmärkningar
En variabel markerad som const
kan inte 1 ändras. Att försöka ringa alla icke-const-operationer på det kommer att leda till ett kompilatorfel.
1: Det kan ändras genom const_cast
, men du bör nästan aldrig använda det
Konstala lokala variabler
Förklaring och användning.
// 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
Bindning av referenser och pekare
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 pekare
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;
Konstmedlemfunktioner
Medlemsfunktioner i en klass kan förklaras const
, som säger kompilatorn och framtida läsare att denna funktion inte kommer att ändra objektet:
class MyClass
{
private:
int myInt_;
public:
int myInt() const { return myInt_; }
void setMyInt(int myInt) { myInt_ = myInt; }
};
I en const
medlemsfunktion är this
pekare effektivt en const MyClass *
istället för en MyClass *
. Detta innebär att du inte kan ändra några medlemsvariabler inom funktionen; kompilatorn avger en varning. Så setMyInt
kunde inte förklaras const
.
Du bör nästan alltid markera medlemsfunktioner som const
när det är möjligt. Endast const
medlemsfunktioner kan anropas på en const MyClass
.
static
metoder kan inte deklareras som const
. Detta beror på att en statisk metod tillhör en klass och inte kallas för objekt; därför kan det aldrig modifiera objektets interna variabler. Att förklara static
metoder som const
skulle vara överflödigt.
Undvika duplicering av kod i const och non-const getter metoder.
I C ++ kan metoder som endast skiljer sig efter const
kvalificeringen överbelastas. Ibland kan det finnas behov av två versioner av getter som returnerar en hänvisning till någon medlem.
Låt Foo
vara en klass, som har två metoder som utför identiska operationer och returnerar en referens till ett objekt av Bar
:
class Foo
{
public:
Bar& GetBar(/* some arguments */)
{
/* some calculations */
return bar;
}
const Bar& GetBar(/* some arguments */) const
{
/* some calculations */
return bar;
}
// ...
};
Den enda skillnaden mellan dem är att en metod är non-const och returnerar en non-const referens (som kan användas för att modifiera objekt) och den andra är const och returnerar const referens.
För att undvika duplicering av koden finns det en frestelse att ringa en metod från en annan. Vi kan emellertid inte kalla icke-const-metoden från const-en. Men vi kan kalla const-metod från icke-const en. Det kommer att kräva att du använder 'const_cast' för att ta bort const-kvalen.
Lösningen är:
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;
}
};
I koden ovan kallar vi const-version av GetBar
från GetBar
-baren som inte är GetBar
genom att kasta den till const type: const_cast<const Foo*>(this)
. Eftersom vi kallar const-metoden från icke-const, är själva objektet icke-const, och att kasta bort const är tillåtet.
Undersök följande mer fullständiga exempel:
#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';
}