Recherche…


Syntaxe

  • const Type myVariable = initial; // déclare une variable const; ne peut pas être changé
  • const Type & myReference = myVariable; // déclare une référence à une variable const
  • const Type * myPointer = & myVariable; // Déclare un pointeur sur const. Le pointeur peut changer, mais le membre de données sous-jacent ne peut pas être modifié via le pointeur
  • Tapez * const myPointer = & myVariable; // Déclare un pointeur const. Le pointeur ne peut pas être réaffecté pour pointer sur autre chose, mais le membre de données sous-jacent peut être modifié
  • const Type * const myPointer = & myVariable; // déclare un const pointeur sur const.

Remarques

Une variable marquée comme const ne peut pas être changé 1. Si vous tentez d'appeler des opérations autres que des const sur cela entraînera une erreur de compilation.

1: Eh bien, il peut être changé par const_cast , mais vous ne devriez presque jamais l'utiliser

Variables locales const

Déclaration et usage

// 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

Reliure de références et de pointeurs

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

Pointeurs Const

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;

Fonctions de membre Const

Les fonctions membres d'une classe peuvent être déclarées const , ce qui indique au compilateur et aux futurs lecteurs que cette fonction ne modifiera pas l'objet:

class MyClass
{
private:
    int myInt_;
public:
    int myInt() const { return myInt_; }
    void setMyInt(int myInt) { myInt_ = myInt; }
};

Dans une fonction membre const , le pointeur this est en fait un const MyClass * au lieu d'un MyClass * . Cela signifie que vous ne pouvez modifier aucune variable membre dans la fonction; le compilateur émettra un avertissement. Donc, setMyInt n'a pas pu être déclaré const .

Vous devriez presque toujours marquer les fonctions des membres comme const lorsque cela est possible. Seules les fonctions de membre const peuvent être appelées sur un const MyClass .

static méthodes static ne peuvent pas être déclarées comme const . En effet, une méthode statique appartient à une classe et n’est pas appelée sur l’objet; par conséquent, il ne peut jamais modifier les variables internes de l'objet. Donc, déclarer static méthodes static comme const serait redondant.

Éviter la duplication du code dans les méthodes get const et non const.

En C ++, les méthodes qui ne diffèrent que par un qualificateur const peuvent être surchargées. Parfois, deux versions de getter peuvent être nécessaires pour renvoyer une référence à un membre.

Soit Foo une classe, qui a deux méthodes qui effectuent des opérations identiques et renvoie une référence à un objet de type Bar :

class Foo
{
public:
    Bar& GetBar(/* some arguments */)
    {
        /* some calculations */
        return bar;
    }
    
    const Bar& GetBar(/* some arguments */) const
    {
        /* some calculations */
        return bar;
    }

    // ...
};

La seule différence entre eux est qu'une méthode est non-const et renvoie une référence non-const (qui peut être utilisée pour modifier un objet) et la seconde est const et renvoie une référence const.

Pour éviter la duplication de code, il est tentant d'appeler une méthode d'une autre. Cependant, nous ne pouvons pas appeler la méthode non-const du const. Mais on peut appeler la méthode const de non-const. Cela nécessitera d'utiliser 'const_cast' pour supprimer le qualificatif const.

La solution est la suivante:

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

Dans le code ci-dessus, nous appelons la version const de GetBar partir du non-const GetBar en le GetBar en const: const_cast<const Foo*>(this) . Puisque nous appelons la méthode const de non-const, l'objet lui-même est non-const, et le rejet de const est autorisé.

Examinez l'exemple plus complet suivant:

#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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow