この章では、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;
}
Player() と Player(string n) の2つのコンストラクタを定義初期化リストは、コンストラクタの処理の前に直接変数を初期化するための仕組みです。
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;
}
次のコードを実行すると何が表示されますか?
#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;
}
h1 は引数なしで生成されるので Hero() が呼ばれ name は "Unknown"。h2("Link") は引数ありなので Hero(string n) が呼ばれ name は "Link"。結果、上から "Unknown が現れた!" → "Link が現れた!" の順で出力されます。
初期化リストを使ったコンストラクタの説明として正しいものはどれですか?
{ } が実行される前に、メンバ変数を直接初期化します。private・publicどちらのメンバにも使用でき、constメンバや参照メンバの初期化に必須です。
次のコードはコンパイルできますか?
class Box {
private:
const int size;
public:
Box(int s) {
size = s; // コンストラクタ本体で代入
}
};
const メンバはオブジェクト生成後に変更できません。コンストラクタ本体 { } に到達した時点ですでに初期化済みでなければならないため、size = s; はエラーになります。正しくは Box(int s) : size(s) {} と初期化リストを使います。
次のコードを実行したとき、出力はどれになりますか?
#include <iostream>
using namespace std;
class Counter {
private:
int count;
public:
Counter() : count(0) {}
Counter(int n) : count(n) {}
void show() { cout << count << endl; }
};
int main() {
Counter c1;
Counter c2(5);
c1.show();
c2.show();
return 0;
}
c1 は引数なしで Counter() が呼ばれ count は 0。c2(5) は Counter(int n) が呼ばれ count は 5。よって出力は 0 → 5 の順になります。
// main.cpp
#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;
}
13_01_CtorOverload の main.cpp をコピーして 13_02_CtorMod に貼り付け、次の変更を加えてみましょう:
Player クラスに int hp メンバを追加するgreet() で名前と HP を表示するように変更する