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

Remarquez que nous fournissons deux versions : l'une retourne une référence non-const (permettant la modification), et la version const fonctionne avec des objets const. Cela vous permet d'écrire arr[0] = 5; pour la lecture et l'écriture.

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 les opérateurs d'indice et d'appel de fonction. Cette classe stockera les scores des joueurs et vous permettra d'y accéder par index en utilisant [], tout en agissant également comme un foncteur qui applique un multiplicateur de bonus à tout score que vous lui passez.

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

  • ScoreTracker.h : Définissez une classe ScoreTracker qui gère un tableau de scores de joueurs et peut appliquer des bonus. Votre classe doit avoir :
    • Un tableau int* alloué dynamiquement pour stocker les scores
    • Un membre size_t pour le nombre de scores
    • Un membre double pour le multiplicateur de bonus
    • Un constructeur qui prend la taille et le multiplicateur de bonus, initialisant tous les scores à 0
    • Un destructeur qui nettoie correctement la mémoire dynamique
    • L'opérateur d'indice [] (versions const et non-const) pour accéder aux scores par index
    • L'opérateur d'appel de fonction () qui prend un score int et retourne le score multiplié par le multiplicateur de bonus (en tant qu'int)
    • Une méthode getSize() qui retourne le nombre de scores

    L'opérateur d'indice non-const retourne 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 séparée) :
    1. Nombre de joueurs (taille)
    2. Multiplicateur de bonus (en tant que double)
    3. Scores pour chaque joueur (un par ligne, autant que 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 avec bonus 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, 150, et 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.

Aide-mémoire

L'opérateur d'indice [] permet d'accéder aux objets comme à des tableaux. L'opérateur d'appel de fonction () rend les objets appelables comme des fonctions (foncteurs).

Opérateur d'indice

Fournissez des versions const et non-const pour l'accès en lecture/écriture :

class IntArray {
    int* data;
    size_t size;
    
public:
    IntArray(size_t s) : size(s), data(new int[s]()) {}
    ~IntArray() { delete[] data; }
    
    // Non-const version: allows modification
    int& operator[](size_t index) {
        return data[index];
    }
    
    // Const version: read-only access
    const int& operator[](size_t index) const {
        return data[index];
    }
};

Opérateur d'appel de fonction

Crée des foncteurs qui peuvent maintenir un état entre les appels :

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);    // Returns 30

Les foncteurs sont utiles avec les algorithmes de la STL lorsqu'un comportement personnalisable avec une configuration stockée est nécessaire.

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