Menu
Coddy logo textTech

Fonctions membres const

Fait partie de la section Programmation Orientée Objet du Journey C++ de Coddy — leçon 29 sur 104.

Vous avez vu le mot-clé const sur les méthodes getter dans la leçon précédente. Mais que signifie exactement const lorsqu'il apparaît après la liste des paramètres d'une fonction ? Une fonction membre const promet de ne modifier aucune variable membre de l'objet.

class Rectangle {
    int width;
    int height;
public:
    Rectangle(int w, int h) : width(w), height(h) {}
    
    int getArea() const {      // fonction membre constante
        return width * height;  // La lecture des membres est autorisée
    }
    
    void setWidth(int w) {     // Non-const - modifie l'objet
        width = w;
    }
};

Le mot-clé const après la liste des paramètres indique au compilateur : « Cette fonction ne modifiera pas l'état de l'objet. » Si vous essayez de modifier une variable membre à l'intérieur d'une fonction const, le compilateur générera une erreur.

Cela devient essentiel lorsqu'on travaille avec des objets const ou des références const. Un objet const ne peut appeler que des fonctions membres const :

void printArea(const Rectangle& rect) {
    std::cout << rect.getArea();    // OK - getArea() est const
    // rect.setWidth(10);           // ERREUR - setWidth() n'est pas const
}

Marquer les fonctions comme const lorsqu'elles ne modifient pas l'objet est une bonne pratique. Cela documente votre intention, permet à la fonction de fonctionner avec des objets const, et aide le compilateur à détecter les modifications accidentelles. Toute fonction membre qui ne fait que lire des données devrait être marquée const.

challenge icon

Défi

Facile

Construisons un convertisseur de température qui démontre quand et pourquoi utiliser des fonctions membres const. Vous allez créer une classe où certaines méthodes ne font que lire des données (et devraient être const) tandis que d'autres modifient l'état de l'objet.

Vous allez créer deux fichiers pour organiser votre code :

  • Temperature.h : Définissez une classe Temperature qui stocke une valeur de température et fournit diverses manières de la lire et de la modifier. Votre classe doit avoir :
    • Un membre privé celsius (double) pour stocker la température
    • Un constructeur qui prend une valeur Celsius initiale
    • Une méthode getCelsius() qui retourne la valeur stockée — celle-ci doit être const puisqu'elle ne fait que lire des données
    • Une méthode getFahrenheit() qui calcule et retourne la température en Fahrenheit en utilisant la formule celsius * 9.0 / 5.0 + 32.0 — également const puisqu'elle ne modifie rien
    • Une méthode getKelvin() qui retourne la température en Kelvin en utilisant celsius + 273.15 — const également
    • Une méthode setCelsius(double value) qui met à jour la température stockée — celle-ci ne peut pas être const puisqu'elle modifie l'objet
    • Une méthode adjustBy(double delta) qui ajoute le delta à la température actuelle — également non-const
  • main.cpp : Démontrez comment les fonctions membres const fonctionnent avec des objets réguliers et des objets const. Lisez une valeur de température initiale à partir de l'entrée, puis :
    • Créez un objet Temperature avec la valeur d'entrée
    • Affichez "Initial: <celsius>C = <fahrenheit>F = <kelvin>K"
    • Ajustez la température de 10.0 degrés
    • Affichez "After adjustment: <celsius>C"
    • Créez une fonction auxiliaire void printReadings(const Temperature& temp) qui prend une référence const et affiche "Reading: <celsius>C, <fahrenheit>F" — cette fonction ne peut appeler que des méthodes const sur temp
    • Appelez printReadings() avec votre objet de température
    • Réglez la température à 0.0 (point de congélation)
    • Affichez "Freezing point: <celsius>C = <fahrenheit>F"

Formatez toutes les valeurs de température avec une décimale en utilisant std::fixed et std::setprecision(1) de <iomanip>.

L'idée clé ici est que printReadings() reçoit une référence const, elle ne peut donc appeler que des méthodes marquées comme const. C'est pourquoi il est important de marquer correctement vos méthodes "getter" comme const — cela leur permet de fonctionner dans des contextes où l'objet ne peut pas être modifié.

Aide-mémoire

Une fonction membre const promet de ne modifier aucune variable membre de l'objet. Le mot-clé const est placé après la liste des paramètres de la fonction :

class Rectangle {
    int width;
    int height;
public:
    int getArea() const {      // fonction membre const
        return width * height;  // La lecture des membres est autorisée
    }
    
    void setWidth(int w) {     // Non-const - modifie l'objet
        width = w;
    }
};

Les fonctions membres const peuvent uniquement lire les variables membres, pas les modifier. Si vous essayez de modifier une variable membre à l'intérieur d'une fonction const, le compilateur produira une erreur.

Un objet const ou une référence const ne peut appeler que des fonctions membres const :

void printArea(const Rectangle& rect) {
    std::cout << rect.getArea();    // OK - getArea() est const
    // rect.setWidth(10);           // ERREUR - setWidth() n'est pas const
}

Marquez les fonctions comme const lorsqu'elles ne modifient pas l'objet. Cela documente votre intention, permet à la fonction de travailler avec des objets const et aide le compilateur à détecter les modifications accidentelles. Toute fonction membre qui ne fait que lire des données devrait être marquée const.

Essayez vous-même

#include <iostream>
#include <iomanip>
#include "Temperature.h"
using namespace std;

// TODO: Implémenter les méthodes de la classe Temperature ici
// Constructeur
Temperature::Temperature(double initialCelsius) {
    // TODO: Initialiser celsius
}

// TODO: Implémenter getCelsius() en tant que const

// TODO: Implémenter getFahrenheit() en tant que const

// TODO: Implémenter getKelvin() en tant que const

// TODO: Implémenter setCelsius(double value)

// TODO: Implémenter adjustBy(double delta)


// TODO: Créer une fonction auxiliaire printReadings qui prend un const Temperature& 
// et affiche "Reading: <celsius>C, <fahrenheit>F"
// Note: Cette fonction ne peut appeler que des méthodes const sur temp !


int main() {
    double initialTemp;
    cin >> initialTemp;

    // Définir le formatage de la sortie
    cout << fixed << setprecision(1);

    // TODO: Créer un objet Temperature avec la valeur d'entrée

    // TODO: Afficher "Initial: <celsius>C = <fahrenheit>F = <kelvin>K"

    // TODO: Ajuster la température de 10.0 degrés

    // TODO: Afficher "After adjustment: <celsius>C"

    // TODO: Appeler printReadings() avec votre objet temperature

    // TODO: Régler la température à 0.0 (point de congélation)

    // TODO: Afficher "Freezing point: <celsius>C = <fahrenheit>F"

    return 0;
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet