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


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow