C/C++ Arena

Step 3 of 9

Constructors

A constructor is a special member function that runs automatically when an object is created. It sets the object up so it's valid from the first moment. It has the same name as the class and no return type.

#include <iostream>
#include <string>

class Book {
public:
    Book(std::string title, int pages) : title_(title), pages_(pages), read_(0) {}

    void read(int n) {
        read_ += n;
        if (read_ > pages_) read_ = pages_;
    }
    int percent() const { return read_ * 100 / pages_; }
    std::string title() const { return title_; }

private:
    std::string title_;
    int pages_;
    int read_;
};

int main() {
    Book b("Dune", 400);
    b.read(100);
    std::cout << b.title() << ": " << b.percent() << "%\n";
    Book c{"Emma", 300};
    std::cout << c.title() << ": " << c.percent() << "%\n";
}
Dune: 25%
Emma: 0%

The member initializer list

The part after the : is the member initializer list: title_(title) initializes the member title_ from the parameter title, and so on. Members are constructed directly with these values, before the constructor's body runs. The body ({} here) can then do any extra work.

Creating objects

Book b("Dune", 400); and Book c{"Emma", 300}; both call the constructor. The brace form (uniform initialization) is common in modern C++ and refuses narrowing conversions, like silently turning 3.7 into an int.

Braces have one more rule. A constructor taking a std::initializer_list<T> (from <initializer_list>) accepts a brace list of any length, and when one exists, braces prefer it. That's how std::vector<int> v{1, 2, 3} holds three values, and why std::vector<int> v{3, 7} holds 3 and 7 while std::vector<int> v(3, 7) holds three 7s. Your own classes can take a list the same way: Bag(std::initializer_list<int> items) { for (int x : items) add(x); }.

Once a class has a constructor with parameters, you can't create one without arguments (Book d; is an error) unless you also write a constructor that takes none. That's the point: there's no way to get a Book without a title and a page count.

Your turn: complete the constructor's initializer list.

Previous: public and private Next: const member functions