Menu
Coddy logo textTech

Constructor Init Lists

Part of the Object Oriented Programming section of Coddy's C++ journey — lesson 22 of 104.

You've seen the colon syntax in previous lessons like Player(std::string n, int h) : name(n), health(h) {}. This is called a member initializer list, and it's the preferred way to initialize members in C++.

The initializer list appears after the constructor's parameter list, starting with a colon. Each member is initialized directly with its value, separated by commas:

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) {
        // Constructor body (can be empty)
    }
};

Why use initializer lists instead of assignment in the constructor body? With assignment, members are first default-constructed, then assigned new values. With initializer lists, members are constructed directly with the correct values - more efficient and sometimes required.

Certain members must be initialized using the list:

  • const members - cannot be assigned after construction
  • Reference members - must be bound at initialization
  • Members without default constructors
class Player {
    const int maxHealth;    // Must use initializer list
    std::string name;
public:
    // This works
    Player(int max, std::string n) : maxHealth(max), name(n) {}
    
    // This would NOT compile:
    // Player(int max) { maxHealth = max; }  // Error!
};

Members are initialized in the order they're declared in the class, not the order in the initializer list. Always write your initializer list in declaration order to avoid confusion.

challenge icon

Challenge

Easy

Let's build a configuration system for a game engine that demonstrates when and why member initializer lists are essential. You'll create a GameConfig class with members that must be initialized using the initializer list syntax.

You'll create two files to organize your code:

  • GameConfig.h: Define a GameConfig class that stores game settings. Your class should have:
    • A const std::string gameName — the game's title, which cannot change after creation
    • A const int maxPlayers — the maximum player count, fixed at construction
    • An int& difficultyRef — a reference to an external difficulty setting
    • An int screenWidth and int screenHeight — regular members for display settings
    • A constructor that takes all necessary parameters and initializes every member using the initializer list. The initializer list should follow the order members are declared in the class
    • A display() method that prints the configuration in this format:
      Game: <gameName>
      Max Players: <maxPlayers>
      Difficulty: <difficultyRef value>
      Resolution: <screenWidth>x<screenHeight>
  • main.cpp: Read configuration values from input and create a GameConfig object. You'll need:
    • Read the game name (string), max players (int), difficulty (int), width (int), and height (int) from input — each on a separate line
    • Create a local int variable for difficulty that the config will reference
    • Create a GameConfig object using the initializer list constructor
    • Call display() to show the initial configuration
    • Modify the difficulty variable directly (multiply it by 2)
    • Print "After difficulty change:"
    • Call display() again to show that the reference reflects the updated value

This challenge highlights why initializer lists matter: your const members and reference member cannot be assigned in the constructor body — they must be initialized in the list. The reference member also demonstrates how changes to the original variable are reflected through the config object.

Include your header file in main.cpp using #include "GameConfig.h".

Cheat sheet

A member initializer list is the preferred way to initialize class members in C++. It appears after the constructor's parameter list, starting with a colon, with each member initialized directly:

class Rectangle {
    int width;
    int height;
public:
    Rectangle(int w, int h) : width(w), height(h) {
        // Constructor body
    }
};

Why use initializer lists? Members are constructed directly with the correct values instead of being default-constructed and then assigned, making it more efficient.

Required for certain members:

  • const members - cannot be assigned after construction
  • Reference members - must be bound at initialization
  • Members without default constructors
class Player {
    const int maxHealth;
    int& reference;
public:
    // Correct - uses initializer list
    Player(int max, int& r) : maxHealth(max), reference(r) {}
    
    // Error - cannot assign const or reference in body
    // Player(int max) { maxHealth = max; }
};

Important: Members are initialized in the order they're declared in the class, not the order in the initializer list. Always write your initializer list in declaration order.

Try it yourself

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

using namespace std;

int main() {
    // Read input values
    string gameName;
    getline(cin, gameName);
    
    int maxPlayers;
    cin >> maxPlayers;
    
    int difficulty;
    cin >> difficulty;
    
    int width;
    cin >> width;
    
    int height;
    cin >> height;
    
    // TODO: Create a GameConfig object using the initializer list constructor
    // The constructor should receive: gameName, maxPlayers, difficulty (by reference), width, height
    
    // TODO: Call display() to show the initial configuration
    
    // TODO: Modify the difficulty variable directly (multiply it by 2)
    
    // TODO: Print "After difficulty change:"
    
    // TODO: Call display() again to show the updated configuration
    
    return 0;
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming