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 30Les 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.
Défi
FacileConstruisons 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 classeScoreTrackerqui 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_tpour le nombre de scores - Un membre
doublepour 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 scoreintet 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éconstpuisqu'il ne modifie pas l'état de l'objet.- Un tableau
main.cpp: Lisez les entrées suivantes (chacune sur une ligne séparée) :- Nombre de joueurs (taille)
- Multiplicateur de bonus (en tant que double)
- Scores pour chaque joueur (un par ligne, autant que la taille)
- 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: 120Utilisez 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 30Les 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;
}
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
1Fondamentaux de la POO
Fichiers externesBuild et Compilation C++Fichiers d'en-tête et Fichiers sourceEspaces de noms et PortéeIntroduction à la POO en C++Classes vs ObjetsLe pointeur 'this'Méthodes (Fonctions membres)Attributs (Membres de données)Bases des Ctors et DtorsRécapitulatif - Calculatrice simple4Propriétés de classe
Membres d'instance vs membres statiquesGetters et SettersFonctions membres constMot-clé mutableMéthodes et variables statiquesFonctions et classes amiesRécapitulatif - Gestionnaire de compte bancaire7Héritage
Héritage de baseNiveaux d'accès à l'héritageOrdre d'appel des Ctor et DtorRedéfinition de méthodesFonctions virtuelles et VTableHéritage multipleHéritage virtuelRécapitulatif - Hiérarchie des employés10Présentation de la STL
Présentation et philosophie de la STLConteneurs de la STLItérateursAlgorithmes de la STLFoncteurs et expressions lambdaRécapitulatif - Fréquence des mots13Patrons de conception, Partie 1
Introduction aux patrons de conceptionPatron SingletonFabrique & Fabrique abstraitePatron MonteurPatron ObservateurPatron Stratégie2Gestion de la mémoire
Mémoire Pile vs TasPointeurs et RéférencesMémoire dynamique (new/delete)Smart Pointers en C++RAII en C++Récapitulatif - Gestionnaire de tableaux dynamiques5Encapsulation
Spécificateurs d'accès en C++Spécificateurs d'accès en profondeurMasquage d'informationStruct vs ClassClasses imbriquées et internesRécapitulatif - Système de gestion d'étudiants8Polymorphisme
Polymorphisme : Compilation vs ExécutionSurcharge de fonctionsRetour sur les fonctions virtuellesFonctions virtuelles puresClasses abstraitesConception d'interfaces en C++Dynamic Casting & RTTIRécapitulatif - Calculateur de formes11Concepts avancés de la POO
Composition vs HéritageMixins via CRTPIdiome PimplEffacement de typeEnum Classes & Typage fortGestion des exceptions en POOHiérarchies d'exceptions personnalisées14Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositeRAII en tant que patron3Constructeurs et Destructeurs
Constructeur par défautConstructeur paramétréConstructeur de copieConstructeur de déplacementListes d'initialisation du constructeurConstructeurs déléguésAnalyse approfondie du destructeurRègle de trois / cinq / zéroRécapitulatif - Classe String6Surcharge d'opérateurs
Introduction à la surcharge d'opérateursSurcharge des opérateurs arithmétiquesSurcharge des opérateurs de comparaisonOpérateurs de fluxSurcharge de l'opérateur d'affectationSurcharge des opérateurs [] et ()Opérateurs de conversion de typeRécapitulatif - Classe Matrix9Templates
Templates de fonctionsTemplates de classesSpécialisation de templatesTemplates variadiquesBases de SFINAE & Type TraitsRécapitulatif - Conteneur générique