さっそくだが、以下の短いC++のコードを見てもらおう
func関数内で、Hogeクラスのインスタンスを作るだけのコードである。
(1)~(4)のそれぞれは、(a)、(b)どちらのコンストラクタが呼ばれるか分かるだろうか。
#include <iostream>
int aaa=5;
class Hoge
{
public:
Hoge() { // (a)
std::cout<<"constructor 1"<<std::endl;
};
Hoge(int bbb) { //(b)
std::cout<<"constructor 2"<<std::endl;
};
};
void func(int ccc)
{
Hoge(); // (1)
Hoge(5); // (2)
Hoge(aaa); // (3)
Hoge(ccc); // (4)
}
int main() {
func(5);
return 0;
}
【回答】
◆ (1)は(a)である。説明不要でいいだろう。
◆ (2)は(b)である。これも説明はいらないだろう。
◆ (3)は(a)である!!
引数のないコンストラクタが呼ばれるのだ。
なぜか。
例えば次の場合、
int(5) は5のint型へのキャストである。曖昧性はない。
int(a) はaのint型へのキャスト、もしくは、
int型の変数aの宣言ともとれる。
このような曖昧性がある場合は、宣言と見なすのがC++の仕様である。
(3)に戻ろう。
Hoge(aaa)は、
aaa変数がキャストされているのか、
Hoge型の変数aaaの宣言か分からない。
しかし、仕様により後者を優先する。
Hoge(aaa) ⇒ Hoge aaa
どうしても引数aaaを使いたければ、
Hoge(hoge)(aaa) とすればよい。
もちろん Hoge hoge(aa) でもよい。
さて、
◆ (4) はどうか。
実は、コンパイルエラーになる。
エラーメッセージ:"declaration of 'ccc' shadows a parameter"
cccの宣言(declaration of 'ccc')が、引数(a parameter)を隠してしまう(shadows)からである。