Menu
Coddy logo textTech

Surcharge des opérateurs [] et ()

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

L'opérateur d'indice ([]) permet à votre classe de se comporter comme un tableau, offrant un accès indexé aux éléments. L'opérateur d'appel de fonction (()) transforme les objets en entités appelables, connues sous le nom de foncteurs.

Voici un simple wrapper de tableau avec l'opérateur d'indice :

class IntArray {
    int* data;
    size_t size;
    
public:
    IntArray(size_t s) : size(s), data(new int[s]()) {}
    ~IntArray() { delete[] data; }
    
    int& operator[](size_t index) {
        return data[index];
    }
    
    const int& operator[](size_t index) const {
        return data[index];
    }
};

Notez que nous fournissons deux versions : l’une renvoie une référence non const (permettant la modification), et la version const fonctionne avec les objets const. Cela vous permet d’écrire arr[0] = 5; pour lire et écrire.

L'opérateur d'appel de fonction crée des objets qui peuvent être « appelés » comme des fonctions :

class Multiplier {
    int factor;
    
public:
    Multiplier(int f) : factor(f) {}
    
    int operator()(int value) const {
        return value * factor;
    }
};

Multiplier triple(3);
int result = triple(10);    // Retourne 30

Les foncteurs sont puissants car ils peuvent maintenir un état entre les appels, contrairement aux fonctions classiques. Ils sont couramment utilisés avec les algorithmes de la STL où vous avez besoin d'un comportement personnalisable qui mémorise des valeurs de configuration.

challenge icon

Défi

Facile

Construisons une classe ScoreTracker qui combine à la fois l’opérateur d’indice et l’opérateur d’appel de fonction. Cette classe stockera les scores des joueurs et vous permettra d’y accéder par indice à l’aide de [], tout en agissant comme un foncteur qui applique un multiplicateur de bonus à tout score que vous lui transmettrez.

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

  • ScoreTracker.h : définissez une classe ScoreTracker qui gère un tableau de scores des joueurs et peut appliquer des bonus. Votre classe doit comporter :
    • un tableau int* alloué dynamiquement pour stocker les scores
    • un membre size_t indiquant le nombre de scores
    • un membre double pour le multiplicateur de bonus
    • un constructeur qui prend la taille et le multiplicateur de bonus, en initialisant tous les scores à 0
    • un destructeur qui libère correctement la mémoire dynamique
    • l’opérateur d’indice [] (dans ses versions const et non const) pour accéder aux scores par indice
    • l’opérateur d’appel de fonction () qui prend un score int et renvoie le score multiplié par le multiplicateur de bonus (sous forme de int)
    • une méthode getSize() qui renvoie le nombre de scores

    L’opérateur d’indice non const renvoie une référence afin que vous puissiez écrire tracker[0] = 100;. La version const permet un accès en lecture seule pour les objets const. L’opérateur d’appel de fonction doit être marqué const, puisqu’il ne modifie pas l’état de l’objet.

  • main.cpp : lisez les entrées suivantes (chacune sur une ligne distincte) :
    1. Nombre de joueurs (taille)
    2. Multiplicateur de bonus (sous forme de double)
    3. Scores de chaque joueur (un par ligne, au nombre indiqué par la taille)
    4. Un score de test auquel appliquer le bonus

    Créez un ScoreTracker, utilisez l’opérateur d’indice pour stocker le score de chaque joueur, puis affichez tous les scores. Enfin, utilisez l’opérateur d’appel de fonction pour calculer le score auquel le bonus a été appliqué.

    Format de sortie :

    Player 0: <score>
    Player 1: <score>
    ...
    Bonus applied to <test_score>: <result>

Par exemple, avec 3 joueurs, un multiplicateur de 1.5, des scores de 100, 200 et 150, ainsi qu’un score de test de 80 :

Player 0: 100
Player 1: 200
Player 2: 150
Bonus applied to 80: 120

Utilisez std::stoi() et std::stod() pour la conversion des entrées. N’oubliez pas les gardes d’inclusion dans votre fichier d’en-tête.

Essayez vous-même

#include <iostream>
#include <string>
#include "ScoreTracker.h"

using namespace std;

// TODO: Implémenter le constructeur de ScoreTracker
ScoreTracker::ScoreTracker(size_t size, double multiplier) {
    // TODO: Initialiser les membres et allouer le tableau dynamique
    // Initialiser tous les scores à 0
}

// TODO: Implémenter le destructeur de ScoreTracker
ScoreTracker::~ScoreTracker() {
    // TODO: Nettoyer la mémoire dynamique
}

// TODO: Implémenter l'opérateur d'indice (subscript) non-const

// TODO: Implémenter l'opérateur d'indice (subscript) const

// TODO: Implémenter l'opérateur d'appel de fonction

// TODO: Implémenter la méthode getSize
size_t ScoreTracker::getSize() const {
    // TODO: Retourner le nombre de scores
}

int main() {
    string line;
    
    // Lire le nombre de joueurs
    getline(cin, line);
    size_t numPlayers = stoi(line);
    
    // Lire le multiplicateur de bonus
    getline(cin, line);
    double multiplier = stod(line);
    
    // TODO: Créer ScoreTracker avec numPlayers et multiplier
    
    // TODO: Lire les scores pour chaque joueur et les stocker en utilisant l'opérateur d'indice
    
    // TODO: Lire le score de test
    
    // TODO: Afficher tous les scores des joueurs au format : "Player X: <score>"
    
    // TODO: Afficher le résultat du bonus appliqué au format : "Bonus applied to <test_score>: <result>"
    
    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

Entraînez-vous par vous-même : Compilateur C++ en ligne