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


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow