引数なしのコンストラクタの事をデフォルトコンストラクタと言います。
コンストラクタを記述しない場合に、
コンパイラが勝手に適切なコンストラクタを
用意してくれる機能ではないので、注意して下さい。
引数なしのコンストラクタは、
クラスオブジェクトのインスタンスを引数なしで
記述した場合に呼ばれるので、非常に呼ばれる機会が多くなります。
つまり、引数を記述しなかった場合に
「デフォルト(初期設定)」で呼び出されるコンストラクタ。
と言う意味を持っているため、デフォルトコンストラクタと呼ばれます。
デフォルトコンストラクタ呼び出し例
class Cdata {
public:
int a;
Cdata(); // 引数なしのコンストラクタ
// つまり、デフォルトコンストラクタ
Cdata(int data); // 引数1個のコンストラクタ
};
Cdata::Cdata() { // デフォルトコンストラクタ
a = 0;
}
Cdata::Cdata(int data) { // 引数1個のコンストラクタ
a = data;
}
void main(void) {
Cdata A; // デフォルトコンストラクタ呼び出し
Cdata B(10); // 引数1個のコンストラクタ呼び出し
}
このプログラムでは、クラスCdataにデフォルトコンストラクタと
引数1個のコンストラクタを記述した例です。
Cdata A;のように、引数を記述しなかった場合は、
引数なしのデフォルトコンストラクタが呼ばれます。
Cdata B(10);のように1つの引数を記述すれば、
引数1個のコンストラクタが呼ばれます。
省略可能引数を使ったデフォルトコンストラクタ
デフォルトコンストラクタは、
引数がないコンストラクタの事を指しますが、
省略可能引数を使い、
引数がなしでも呼べるようになっているコンストラクタも
デフォルトコンストラクタになります。
プログラム例
class Cdata {
public:
int a;
Cdata(int data = 0); // デフォルト引数を指定し、
// 引数0個でも呼び出せる形式の
// デフォルトコンストラクタ
};
Cdata::Cdata(int data) { // デフォルトコンストラクタ
a = data;
}
void main(void) {
Cdata A; // デフォルトコンストラクタ呼び出し
Cdata B(10); // デフォルトコンストラクタ呼び出し
}
このプログラムでは、クラスCdataに省略可能引数が設定され、
引数がなしでも呼べる形式になっているコンストラクタが記述されています。
このコンストラクタがデフォルトコンストラクタになります。
Cdata A;と記述すると、
デフォルト引数を使ったデフォルトコンストラクタが呼ばれます。
Cdata B(10);と記述すると、
1つの引数を使ったデフォルトコンストラクタが呼ばれます。
引数を指定しなくても呼べる形式になっていればいいので、
省略可能引数を複数使うコンストラクタも
デフォルトコンストラクタとして働く可能性があります。
class Cdata {
public:
int a;
int b;
Cdata(int data1 = 0, int data2 = 0);
};
// デフォルトコンストラクタとして働く
Cdata::Cdata(int data1, int data2) {
a = data1;
b = data2;
}
引数なしのデフォルトコンストラクタと
省略可能引数を使ったデフォルトコンストラクタの共存
今まで説明した引数なしのデフォルトコンストラクタと、
省略可能引数を使って、引数を指定しなくても呼べる形式になっている
デフォルトコンストラクタを両方とも記述する事は可能でしょうか?
答えはノーです。
なぜなら、引数を指定せずにクラスのインスタンスを作成する場合、
どちらのデフォルトコンストラクタを呼び出すか
コンパイラが判断できないからです。
2つのデフォルトコンストラクタを記述した例
class Cdata {
public:
int a;
Cdata();
Cdata(int data = 0);
};
Cdata::Cdata() { // 1つ目のデフォルトコンストラクタ
a = 0;
}
Cdata::Cdata(int data) { // 2つ目のデフォルトコンストラクタ
a = data;
}
void main(void) {
Cdata A; // どちらのデフォルトコンストラクタを呼び出す?
}
このプログラムは、上記で説明した通り、
コンパイルエラーになり、実行できません。
デフォルトコンストラクタは1つだけ記述するようにしましょう。