C++/CLIをつつく13ーコンストラクタ。うっかりミスを防ごう。
チッチッチチッチッチチッチッチチッチッチチッチッチチッチッチ
継承?残念、まだやることがあるよ。 前回の最後のサンプルプログラムの一部を見てみよう。
int main(array< System::String ^ >^ args)
{
Bird^ b = gcnew Bird() ;
b->Name = "インドリ";
b->Age = 29;
b->Talk( );
b->Name = "ドリィちゃん";
b->Age = -20;
b->Talk( );
Console::WriteLine(
"ドリィちゃん、ボクと同じ年齢なんだね♪" );
return 0;
}
どう?何か気付かない?もっとおかしな点を狭めてみてみよう。Bird^ b = gcnew Bird() ; b->Name = "インドリ"; b->Age = 29; b->Name = "ドリィちゃん"; b->Age = -20;一々名前と年齢を指定するなんて凄く面倒だよね。
だから・・・
Bird b = gcnew Bird( "インドリ", 29 );って変数を作る際に指定できれば便利だし、 名前と年齢の値の指定忘れを防げるよね。 勿論、プログラム言語を作った偉い人はその方法を用意しているよ。
それがコンストラクタなんだ。
では、さっそくコンストラクタを作ってみよう。
public ref class Bird
{
//フィールド
private:
Int32 m_age;
String^ m_name;
Bird(){} //隠したいコンストラクタ
public:
property Int32 Age {
Int32 get() { return this->m_age; }
void set( Int32 value ) {
if ( value > 0 ) m_age = value;
}
}
property String^ Name;
//コンストラクタ
Bird ( String^ name, Int32 age ) {
this->Name = name;
this->Age = age;
}
void Talk( ) {
Console::WriteLine( "私は{0}。年は{1}だよ。",
this->Name, this->Age);
}
};
Birdクラスのコードをこう変えてコンパイルしてみよう。すると・・・
error C3767: 'Sample::Bird::Bird': 候補の関数はアクセス可能ではありません。とエラーが出るよね。これでいいんだ。 こうすることにより名前と年齢を指定し忘れる事がなくなるピヨ。 ところで、何でBird()コンストラクタを隠す必要があったのか気になった人がいるかもしれないから説明しておくピヨ。それは、引数を取るコンストラクタ(受け取る変数が定義されている)を作成したら、必ず引数がないコンストラクタを必ず定義しなくちゃならないからだよ。何でかって?それはコンパイラがそうなっているからなんだ。今のところあまり気にする必要がはないピヨ。
鳥頭のボクには最適な機能だね。こうすると使用するプログラムは次の様になるよ。
int main(array< System::String ^> ^args)
{
Bird^ b = gcnew Bird( "インドリ", 29 ) ;
b->Talk( );
b->Name = "ドリィちゃん";
b->Age = -20;
b->Talk( );
Console::WriteLine(
"ドリィちゃん、ボクと同じ年齢なんだね♪" );
return 0;
}
コンストラクタの部分はこれでお終い。でもひとつ注意があるピヨ。それは・・・コンストラクタは必要最低限定義しよう ということピヨ。コンストラクタを覚えたての頃は嬉しくて「よーし全部のプロパティを指定できるコンストラクタを作るぞ!」 と思ってしまうかもしれない。だけど、コンストラクタはあくまでも 絶対必要なものだけを指定するものなんだ。 注意してね。