13:コンストラクタのオーバーロードと初期化リスト

はじめに

この章では、C++でクラスをさらに柔軟に使うための次の2つを学びます。


コンストラクタのオーバーロードとは

オーバーロードとは「同じ名前で複数のバリエーション」を定義することです。

C++では 同じ名前引数の数や型が異なるものを複数定義でき、呼び出し時に与える引数の形に応じて適切な関数が選ばれる、という仕組みがオーバーロードです。

コンストラクタをオーバーロードすることで、


例:オーバーロードされたコンストラクタ

#include <iostream>
using namespace std;

class Player {
private:
    string name;

public:
    Player() {
        name = "Unknown";
    }

    Player(string n) {
        name = n;
    }

    void greet() {
        cout << "こんにちは、" << name << " さん!" << endl;
    }
};

int main() {
    Player p1;           // 名前指定なし
    Player p2("Yamada");  // 名前指定あり

    p1.greet();
    p2.greet();

    return 0;
}

解説


初期化リスト

初期化リストは、コンストラクタの処理の前に 直接変数を初期化 するための仕組みです。

class Player {
private:
    string name;

public:
    Player(string n) : name(n) {
        // 初期化リストで name に n をセット
    }
};

初期化リストのメリット


初期化リストの実例

#include <iostream>
using namespace std;

class Product {
private:
    string name;
    int price;

public:
    Product(string n, int p) : name(n), price(p) {
        // ここで特に何もしなくても、上で初期化済み
    }

    void show() {
        cout << name << " は " << price << " 円です。" << endl;
    }
};

int main() {
    Product apple("りんご", 150);
    apple.show();

    return 0;
}

理解度チェック

問題1(13_constructor_overload_test.cpp)

次のコードを実行すると何が表示されますか?

#include <iostream>
using namespace std;

class Hero {
private:
    string name;

public:
    Hero() : name("Unknown") {}
    Hero(string n) : name(n) {}

    void show() {
        cout << name << " が現れた!" << endl;
    }
};

int main() {
    Hero h1;
    Hero h2("Link");

    h1.show();
    h2.show();

    return 0;
}
正解・解説を見る
Unknown が現れた!
Link が現れた!

演習問題

課題(13_rectangle_constructor.cpp)

コードを次のように改善しなさい。

#include <iostream>
using namespace std;

class Rectangle {
public:
    int width;
    int height;

    int area() {
        return width * height;
    }
};

int main() {
    Rectangle r;
    r.width = 5;
    r.height = 3;
    cout << "面積: " << r.area() << endl;

    return 0;
}
解答例を見る
// 13_rectangle_constructor.cpp
#include <iostream>
using namespace std;

class Rectangle {
private:
    int width;
    int height;

public:
    Rectangle() : width(1), height(1) {}
    Rectangle(int w, int h) : width(w), height(h) {}

    int area() {
        return width * height;
    }
};

int main() {
    Rectangle r1;
    Rectangle r2(5, 3);

    cout << "r1の面積: " << r1.area() << endl;
    cout << "r2の面積: " << r2.area() << endl;

    return 0;
}

まとめ