Menu
Coddy logo textTech

Sobrecarga dos Operadores [] e ()

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy. Lição 45 de 104.

O operador de subscrito ([]) permite que sua classe se comporte como um array, fornecendo acesso indexado aos elementos. O operador de chamada de função (()) transforma objetos em entidades chamáveis, conhecidas como functores.

Aqui está um wrapper de array simples com o operador de subscrito:

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

Observe que fornecemos duas versões: uma retorna uma referência não-const (permitindo modificação), e a versão const funciona com objetos const. Isso permite que você escreva arr[0] = 5; para leitura e escrita.

O operador de chamada de função cria objetos que podem ser "chamados" como funções:

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

Functors são poderosos porque podem manter o estado entre chamadas, ao contrário de funções regulares. Eles são comumente usados com algoritmos da STL onde você precisa de um comportamento personalizável que lembre valores de configuração.

challenge icon

Desafio

Fácil

Vamos criar uma classe ScoreTracker que combina os operadores de subscrito e de chamada de função. Essa classe armazenará as pontuações dos jogadores e permitirá que você as acesse por índice usando [], além de atuar como um funtor que aplica um multiplicador de bônus a qualquer pontuação que você passar para ela.

Você criará dois arquivos para organizar seu código:

  • ScoreTracker.h: defina uma classe ScoreTracker que gerencie um array de pontuações dos jogadores e possa aplicar bônus. Sua classe deve ter:
    • Um array int* alocado dinamicamente para armazenar as pontuações
    • Um membro size_t para a quantidade de pontuações
    • Um membro double para o multiplicador de bônus
    • Um construtor que receba o tamanho e o multiplicador de bônus, inicializando todas as pontuações com 0
    • Um destrutor que libere corretamente a memória dinâmica
    • O operador de subscrito [] (nas versões const e não-const) para acessar as pontuações por índice
    • O operador de chamada de função (), que receba uma pontuação int e retorne a pontuação multiplicada pelo multiplicador de bônus (como um int)
    • Um método getSize() que retorne a quantidade de pontuações

    O operador de subscrito não-const retorna uma referência, para que você possa escrever tracker[0] = 100;. A versão const permite acesso somente para leitura a objetos const. O operador de chamada de função deve ser marcado como const, pois não modifica o estado do objeto.

  • main.cpp: leia as seguintes entradas (cada uma em uma linha separada):
    1. Número de jogadores (tamanho)
    2. Multiplicador de bônus (como um double)
    3. Pontuações de cada jogador (uma por linha, em quantidade igual ao tamanho)
    4. Uma pontuação de teste à qual aplicar o bônus

    Crie um ScoreTracker, use o operador de subscrito para armazenar a pontuação de cada jogador e, em seguida, exiba todas as pontuações. Por fim, use o operador de chamada de função para calcular a pontuação com o bônus aplicado.

    Formato da saída:

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

Por exemplo, com 3 jogadores, um multiplicador de 1.5, pontuações de 100, 200, 150 e uma pontuação de teste igual a 80:

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

Use std::stoi() e std::stod() para a conversão das entradas. Não se esqueça dos guards de inclusão no arquivo de cabeçalho.

Experimente você mesmo

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

using namespace std;

// TODO: Implementar o construtor ScoreTracker
ScoreTracker::ScoreTracker(size_t size, double multiplier) {
    // TODO: Inicializar membros e alocar array dinâmico
    // Inicializar todas as pontuações com 0
}

// TODO: Implementar o destrutor ScoreTracker
ScoreTracker::~ScoreTracker() {
    // TODO: Limpar a memória dinâmica
}

// TODO: Implementar o operador de subscrito não-const

// TODO: Implementar o operador de subscrito const

// TODO: Implementar o operador de chamada de função

// TODO: Implementar o método getSize
size_t ScoreTracker::getSize() const {
    // TODO: Retornar o número de pontuações
}

int main() {
    string line;
    
    // Ler o número de jogadores
    getline(cin, line);
    size_t numPlayers = stoi(line);
    
    // Ler o multiplicador de bônus
    getline(cin, line);
    double multiplier = stod(line);
    
    // TODO: Criar ScoreTracker com numPlayers e multiplier
    
    // TODO: Ler as pontuações de cada jogador e armazenar usando o operador de subscrito
    
    // TODO: Ler a pontuação de teste
    
    // TODO: Exibir todas as pontuações dos jogadores no formato: "Player X: <score>"
    
    // TODO: Exibir o resultado do bônus aplicado no formato: "Bonus applied to <test_score>: <result>"
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos

Pratique por conta própria: Compilador de C++ online