Menu
Coddy logo textTech

Sovraccarico degli operatori [] e ()

Fa parte della sezione Programmazione orientata agli oggetti del percorso C++ di Coddy. Lezione 45 di 104.

L’operatore di indicizzazione ([]) permette alla tua classe di comportarsi come un array, fornendo accesso indicizzato agli elementi. L’operatore di chiamata di funzione (()) trasforma gli oggetti in entità richiamabili, note come functor.

Ecco un semplice wrapper per un array con l’operatore di indicizzazione:

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

Nota che forniamo due versioni: una restituisce un riferimento non const (consentendo la modifica) e la versione const funziona con oggetti const. Questo ti permette di scrivere arr[0] = 5; per leggere e scrivere.

L'operatore di chiamata di funzione crea oggetti che possono essere «chiamati» come funzioni:

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

I funtori sono potenti perché possono mantenere lo stato tra una chiamata e l’altra, a differenza delle funzioni normali. Sono comunemente usati con gli algoritmi STL quando serve un comportamento personalizzabile che memorizzi i valori di configurazione.

challenge icon

Sfida

Facile

Creiamo una classe ScoreTracker che combina sia l’operatore di indicizzazione sia l’operatore di chiamata di funzione. Questa classe memorizzerà i punteggi dei giocatori e ti permetterà di accedervi tramite indice usando [], funzionando anche come funtore che applica un moltiplicatore bonus a qualsiasi punteggio le venga passato.

Creerai due file per organizzare il codice:

  • ScoreTracker.h: definisci una classe ScoreTracker che gestisce un array di punteggi dei giocatori e può applicare bonus. La classe deve avere:
    • Un array int* allocato dinamicamente per memorizzare i punteggi
    • Un membro size_t per il numero di punteggi
    • Un membro double per il moltiplicatore bonus
    • Un costruttore che accetta la dimensione e il moltiplicatore bonus e inizializza tutti i punteggi a 0
    • Un distruttore che libera correttamente la memoria dinamica
    • L’operatore di indicizzazione [] (sia nella versione const sia in quella non-const) per accedere ai punteggi tramite indice
    • L’operatore di chiamata di funzione () che accetta un punteggio int e restituisce il punteggio moltiplicato per il moltiplicatore bonus (come int)
    • Un metodo getSize() che restituisce il numero di punteggi

    L’operatore di indicizzazione non-const restituisce un riferimento, così puoi scrivere tracker[0] = 100;. La versione const consente l’accesso in sola lettura agli oggetti const. L’operatore di chiamata di funzione deve essere contrassegnato come const perché non modifica lo stato dell’oggetto.

  • main.cpp: leggi i seguenti input (ciascuno su una riga separata):
    1. Numero di giocatori (dimensione)
    2. Moltiplicatore bonus (come double)
    3. Punteggi di ciascun giocatore (uno per riga, tanti quanti indicati dalla dimensione)
    4. Un punteggio di prova a cui applicare il bonus

    Crea un ScoreTracker, usa l’operatore di indicizzazione per memorizzare il punteggio di ciascun giocatore, quindi mostra tutti i punteggi. Infine, usa l’operatore di chiamata di funzione per calcolare il punteggio con il bonus applicato.

    Formato dell’output:

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

Per esempio, con 3 giocatori, un moltiplicatore di 1.5, punteggi di 100, 200, 150 e un punteggio di prova di 80:

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

Usa std::stoi() e std::stod() per convertire l’input. Non dimenticare le protezioni anti-inclusione nel file header.

Provalo tu

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

using namespace std;

// TODO: Implementare il costruttore di ScoreTracker
ScoreTracker::ScoreTracker(size_t size, double multiplier) {
    // TODO: Inizializzare i membri e allocare un array dinamico
    // Inizializzare tutti i punteggi a 0
}

// TODO: Implementare il distruttore di ScoreTracker
ScoreTracker::~ScoreTracker() {
    // TODO: Liberare la memoria dinamica
}

// TODO: Implementare l'operatore di indicizzazione non const

// TODO: Implementare l'operatore di indicizzazione const

// TODO: Implementare l'operatore di chiamata di funzione

// TODO: Implementare il metodo getSize
size_t ScoreTracker::getSize() const {
    // TODO: Restituire il numero di punteggi
}

int main() {
    string line;
    
    // Leggere il numero di giocatori
    getline(cin, line);
    size_t numPlayers = stoi(line);
    
    // Leggere il moltiplicatore del bonus
    getline(cin, line);
    double multiplier = stod(line);
    
    // TODO: Crea ScoreTracker con numPlayers e multiplier
    
    // TODO: Leggi i punteggi di ogni giocatore e memorizzali usando l'operatore di indicizzazione
    
    // TODO: Leggi il punteggio di prova
    
    // TODO: Mostra i punteggi di tutti i giocatori nel formato: "Player X: <score>"
    
    // TODO: Mostra il risultato dopo l'applicazione del bonus nel formato: "Bonus applied to <test_score>: <result>"
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C++ online