Menu
Coddy logo textTech

Listas de Inicialização do Construtor

Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 22 de 104.

Você viu a sintaxe de dois pontos em lições anteriores como Player(std::string n, int h) : name(n), health(h) {}. Isso é chamado de lista de inicialização de membros, e é a maneira preferida de inicializar membros em C++.

A lista de inicialização aparece após a lista de parâmetros do construtor, começando com dois pontos. Cada membro é inicializado diretamente com seu valor, separados por vírgulas:

class Rectangle {
    int width;
    int height;
    const int id;
    int& reference;
public:
    Rectangle(int w, int h, int i, int& r) 
        : width(w), height(h), id(i), reference(r) {
        // Corpo do construtor (pode estar vazio)
    }
};

Por que usar listas de inicialização em vez de atribuição no corpo do construtor? Com a atribuição, os membros são primeiro construídos por padrão e, em seguida, recebem novos valores. Com listas de inicialização, os membros são construídos diretamente com os valores corretos — mais eficiente e, às vezes, obrigatório.

Certos membros devem ser inicializados usando a lista:

  • membros const - não podem ser atribuídos após a construção
  • Membros de referência - devem ser vinculados na inicialização
  • Membros sem construtores padrão
class Player {
    const int maxHealth;    // Deve usar lista de inicialização
    std::string name;
public:
    // Isso funciona
    Player(int max, std::string n) : maxHealth(max), name(n) {}
    
    // Isso NÃO compilaria:
    // Player(int max) { maxHealth = max; }  // Erro!
};

Os membros são inicializados na ordem em que são declarados na classe, não na ordem da lista de inicialização. Sempre escreva sua lista de inicialização na ordem de declaração para evitar confusão.

challenge icon

Desafio

Fácil

Vamos construir um sistema de configuração para um motor de jogo que demonstra quando e por que as listas de inicialização de membros são essenciais. Você criará uma classe GameConfig com membros que devem ser inicializados usando a sintaxe de lista de inicialização.

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

  • GameConfig.h: Defina uma classe GameConfig que armazena as configurações do jogo. Sua classe deve ter:
    • Um const std::string gameName — o título do jogo, que não pode mudar após a criação
    • Um const int maxPlayers — a contagem máxima de jogadores, fixa na construção
    • Um int& difficultyRef — uma referência a uma configuração de dificuldade externa
    • Um int screenWidth e int screenHeight — membros regulares para configurações de exibição
    • Um construtor que recebe todos os parâmetros necessários e inicializa cada membro usando a lista de inicialização. A lista de inicialização deve seguir a ordem em que os membros são declarados na classe
    • Um método display() que imprime a configuração neste formato:
      Game: <gameName>
      Max Players: <maxPlayers>
      Difficulty: <difficultyRef value>
      Resolution: <screenWidth>x<screenHeight>
  • main.cpp: Leia os valores de configuração da entrada e crie um objeto GameConfig. Você precisará:
    • Ler o nome do jogo (string), máximo de jogadores (int), dificuldade (int), largura (int) e altura (int) da entrada — cada um em uma linha separada
    • Criar uma variável local int para a dificuldade que a configuração irá referenciar
    • Criar um objeto GameConfig usando o construtor com lista de inicialização
    • Chamar display() para mostrar a configuração inicial
    • Modificar a variável de dificuldade diretamente (multiplicá-la por 2)
    • Imprimir "After difficulty change:"
    • Chamar display() novamente para mostrar que a referência reflete o valor atualizado

Este desafio destaca por que as listas de inicialização são importantes: seus membros const e o membro de referência não podem ser atribuídos no corpo do construtor — eles devem ser inicializados na lista. O membro de referência também demonstra como as alterações na variável original são refletidas através do objeto de configuração.

Inclua seu arquivo de cabeçalho no main.cpp usando #include "GameConfig.h".

Folha de consulta

Uma lista de inicialização de membros é a maneira preferida de inicializar membros de classe em C++. Ela aparece após a lista de parâmetros do construtor, começando com dois pontos, com cada membro inicializado diretamente:

class Rectangle {
    int width;
    int height;
public:
    Rectangle(int w, int h) : width(w), height(h) {
        // Corpo do construtor
    }
};

Por que usar listas de inicialização? Os membros são construídos diretamente com os valores corretos em vez de serem construídos por padrão e depois atribuídos, tornando o processo mais eficiente.

Necessário para certos membros:

  • Membros const - não podem ser atribuídos após a construção
  • Membros de referência - devem ser vinculados na inicialização
  • Membros sem construtores padrão
class Player {
    const int maxHealth;
    int& reference;
public:
    // Correto - usa lista de inicialização
    Player(int max, int& r) : maxHealth(max), reference(r) {}
    
    // Erro - não é possível atribuir const ou referência no corpo
    // Player(int max) { maxHealth = max; }
};

Importante: Os membros são inicializados na ordem em que são declarados na classe, não na ordem na lista de inicialização. Sempre escreva sua lista de inicialização na ordem de declaração.

Experimente você mesmo

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

using namespace std;

int main() {
    // Ler os valores de entrada
    string gameName;
    getline(cin, gameName);
    
    int maxPlayers;
    cin >> maxPlayers;
    
    int difficulty;
    cin >> difficulty;
    
    int width;
    cin >> width;
    
    int height;
    cin >> height;
    
    // TODO: Criar um objeto GameConfig usando o construtor de lista de inicialização
    // O construtor deve receber: gameName, maxPlayers, difficulty (por referência), width, height
    
    // TODO: Chamar display() para mostrar a configuração inicial
    
    // TODO: Modificar a variável difficulty diretamente (multiplicá-la por 2)
    
    // TODO: Imprimir "After difficulty change:"
    
    // TODO: Chamar display() novamente para mostrar a configuração atualizada
    
    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