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'; 
}


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow