C++
Schlüsselwort const
Suche…
Syntax
- const Typ myVariable = initial; // deklariert eine const-Variable; kann nicht geändert werden
- const Type & myReference = meineVariable; // Deklariert einen Verweis auf eine const-Variable
- const Typ * myPointer = & meineVariable; // Deklariert einen Zeiger auf-const. Der Zeiger kann sich ändern, das zugrunde liegende Datenelement kann jedoch nicht über den Zeiger geändert werden
- Geben Sie * const myPointer = & myVariable; // Deklariert einen const-Zeiger. Der Zeiger kann nicht neu zugewiesen werden, um auf etwas anderes zu verweisen, das darunterliegende Datenelement kann jedoch geändert werden
- const Typ * const myPointer = & meineVariable; // Deklariert einen konstanten Zeiger auf eine konstante.
Bemerkungen
Eine Variable als markiert const
kann nicht 1 geändert werden. Wenn Sie versuchen, keine Nicht-Konstanten-Operationen aufzurufen, wird ein Compiler-Fehler ausgegeben.
1: Nun, es kann durch const_cast
geändert werden, aber das sollte man fast nie verwenden
Lokale Variablen definieren
Erklärung und Verwendung.
// 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
Bindung von Referenzen und Verweisen
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
Konstanten
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-Member-Funktionen
Member-Funktionen einer Klasse können als const
deklariert werden. Dies sagt dem Compiler und zukünftigen Lesern, dass diese Funktion das Objekt nicht ändert:
class MyClass
{
private:
int myInt_;
public:
int myInt() const { return myInt_; }
void setMyInt(int myInt) { myInt_ = myInt; }
};
In einer const
Member-Funktion ist this
Zeiger praktisch eine const MyClass *
anstelle einer MyClass *
. Das bedeutet, dass Sie keine Mitgliedsvariablen innerhalb der Funktion ändern können. Der Compiler gibt eine Warnung aus. setMyInt
konnte daher nicht als const
deklariert werden.
Sie sollten const
fast immer als const
markieren, wenn dies möglich ist. Nur const
Member - Funktionen können auf einem heißen const MyClass
.
static
Methoden können nicht als const
deklariert werden. Dies liegt daran, dass eine statische Methode zu einer Klasse gehört und für ein Objekt nicht aufgerufen wird. Daher können die internen Variablen des Objekts niemals geändert werden. Es wäre also überflüssig, static
Methoden als const
zu deklarieren.
Vermeidung der Duplizierung von Code in const- und non-const-Getter-Methoden.
In C ++ - Methoden, die sich nur durch const
Qualifikationsmerkmal unterscheiden, kann es zu einer Überlastung kommen. Manchmal sind zwei Getter-Versionen erforderlich, die einen Verweis auf ein Mitglied zurückgeben.
Sei Foo
eine Klasse mit zwei Methoden, die identische Operationen ausführen und einen Verweis auf ein Objekt vom Typ Bar
:
class Foo
{
public:
Bar& GetBar(/* some arguments */)
{
/* some calculations */
return bar;
}
const Bar& GetBar(/* some arguments */) const
{
/* some calculations */
return bar;
}
// ...
};
Der einzige Unterschied zwischen ihnen besteht darin, dass eine Methode eine Nicht-Konstante ist und eine Nicht-Konstantenreferenz zurückgibt (die zum Ändern des Objekts verwendet werden kann) und die zweite Konstante und eine Konstantenreferenz zurückgibt.
Um die Code-Duplizierung zu vermeiden, besteht die Versuchung, eine Methode von einer anderen aufzurufen. Die non-const-Methode kann jedoch nicht von der const-Methode aufgerufen werden. Die const-Methode können wir jedoch von einer nicht-const-Methode aus aufrufen. Dies erfordert die Verwendung von 'const_cast', um das const-Qualifikationsmerkmal zu entfernen.
Die Lösung ist:
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;
}
};
Im obigen Code rufen wir die const-Version von GetBar
von der nicht-const- GetBar
indem wir dies in const-Typ const_cast<const Foo*>(this)
: const_cast<const Foo*>(this)
. Da wir die const-Methode von non-const aufrufen, ist das Objekt selbst nicht-const und das Verwerfen der const ist erlaubt.
Untersuchen Sie das folgende, vollständigere Beispiel:
#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';
}