C/C++ Arena

Step 7 of 9

Member initializer lists

You've been using the member initializer list since step 3. It's worth understanding exactly why it exists, because some code only works with it.

Initialization vs assignment

Player(std::string name) : name_(name) {}          // initializes name_
Player(std::string name) { name_ = name; }          // default-constructs name_, then assigns

The first constructs name_ directly with the right value. The second first builds an empty name_, then throws that away by assigning. For a string that's a small waste; for some members it's impossible.

Members that must use the list

#include <iostream>
#include <string>

class Sensor {
public:
    Sensor(const std::string& id, double& shared_total, double scale)
        : id_(id), total_(shared_total), scale_(scale) {}

    void record(double raw) { total_ += raw * scale_; }
    const std::string& id() const { return id_; }

private:
    const std::string id_;
    double& total_;
    double scale_;
};

int main() {
    double total = 0;
    Sensor a("a1", total, 1.0);
    Sensor b("b7", total, 0.5);
    a.record(10);
    b.record(10);
    std::cout << a.id() << " " << b.id() << " total " << total << "\n";
}
a1 b7 total 15

Both sensors hold a reference to the same total, and each has a const id that can never change. Neither would compile with assignments in the constructor body.

Order of initialization

Members are initialized in the order they're declared in the class, regardless of the order in the list. If one member's initializer uses another member, the used one must be declared earlier. -Wall warns when the list order differs from the declaration order (field 'a_' will be initialized after field 'b_'), because it hides exactly this bug.

Your turn: give Player a constructor Player(const std::string& name, int max_hp) that sets the const name_, sets max_hp_, and starts hp_ at max_hp_. Use the initializer list for all three.

Previous: Challenge: a Clock class Next: Keeping invariants