Version 3.1
クラスってもの
『今日からバージョン3!』
「でもプロジェクトはこれまでのをそのまま使うから」
『そーよ、計算機早く作りたいもん』
「そのためにももっといろんなことできるようにならないとね」
『はーい』
「さて、今回は〈クラス〉についてみてみましょう」
『クラスって確か、メンバ関数っての持ってて、継承ってのしてるとどれも
使えて……』
「そうそう。今のプロジェクトの CCalcDlg は、MFCの CDialog から継
承してるんだったね」
『でもなんで継承してるの? メンバ関数を使うため?』
「具体的にはそうだけど……じゃ、 CDialog が持ってるメンバ関数って、
どんな機能持ってると思う?」
『そうねぇ……あ、MSDN見たら載ってる?』
「かもね」
『えっと、 CalcDlg.h 開いて……』
「あ、それよりも〈キーワード〉使った方が早いよ」
『なにそれ』
「まずMSDNを開いて、左側に〈目次〉とか〈キーワード〉ってあるで
しょ」
『ってことは、ここに CDialog ……あ、下に CDialog とか出てきた』
「そしたらそれをダブルクリック」
『〈該当するトピック〉が出てきて……〈CDialog クラス メンバ〉でメン
バ関数見られるんだよね』
「そうそう」
『ダブルクリックして……なんかいっぱいメンバ関数あるね』
「どう思う?」
『何が?』
「だから CDialog が持ってるメンバ関数は、どんな機能を持ってるか!」
『あー。えっとね……なんかどれも〈ダイアログボックス〉って書いてある
から……よーするにダイアログ操作するんじゃない?』
「ってことはどういうことだと思う?」
『……うーん、そうねー、 CCalcDlg は、ダイアログの機能を使いたかった
から、CDialog から継承した、ってことなんじゃない?』
「そういうこと! ここでちょっとまとめてみるね」
『うん』
「まずクラスがどこに属してるのかちゃんとしておこうか。 CDialog はM
FCのクラスだよね」
『そうそう』
「じゃあ CCalcDlg は?」
『え? ……えっと、たしか今のプロジェクト、Calc を作ったときに一緒
に作られたんだから……』
「そ、Calc プロジェクトのクラス」
『この違いが重要なの?』
「とっても重要。MFCのクラスは提供されてるのだから勝手に書き換えら
れないでしょ。で、プロジェクトのクラスはプログラマーが作ったのだから」
『自由に書き換えられる!』
「そう! つまりMFCにあるクラスを元に〈継承〉したクラスをプロジェ
クトに作って色々作り替えると、元のクラスに機能を付け加えた〈カスタマ
イズクラス〉を作れるってわけ」
『へ〜、あたしってそんなすごいことしてたんだ』
「まークラス自体は AppWizard が作ってくれたんだけどね」
『あう』
「ってことはね、火美ちゃん」
『な、なに?』
「プログラムを作るってことは、元々あるクラスから継承してアプリ専用の
クラスを作る、ってことなんだよ」
『ウソ! 嘘よ嘘ウソ!』
「ど、どうしたの?」
『前に〈プログラムは関数が集まってできてる〉って言ったじゃない!』
「うん、そうだよ」
『そうだよって素知らぬ顔してババンバーンみたいなこと言って』
「前も言ったねそれ」
『う”、それはともかくとしてぇ』
「だから、その関数が〈メンバ関数〉ってこと」
『へ?』
「カスタマイズクラスを作って、メンバ関数を付けるでしょ。で、メンバ関
数どうし呼び合うようにするわけ。そうすれば、プログラムの完成」
『……うーん、分かったよーな、分かんないよーな……』
「それは、クラスがまだよく分かってないからかな。じゃ、本日最初のプロ
グラム」
void CCalcDlg::OnBEqual()
{
CCalcDlg cDlg;
cDlg.DoModal();
}
『あ、なつかしー、〈ボタンを押したら呼ばれる関数〉だね。で、中は……
え??』
「そ、 CCalcDlg 型の変数、cDlg を作ってます」
『変数って……?』
「つまり、クラスっていうのは int みたいな〈型〉のひとつってこと」
『クラス型の、変数、CCalcDlg の、変数……』
「 int iBox; って感じに〈整数を入れるための変数〉を作ったでしょ。こ
れとおんなじ。〈ダイアログの情報を入れるための変数〉を作ったわけ」
『ダイアログの情報って?』
「どういうダイアログを表示するかとか、あとダイアログのエディットボッ
クスに入ってる数字とか、そういうのを持ってるわけ」
『へ〜、そういうのを持つ変数なのね』
「で、クラス型変数は、値を持つだけじゃなくて、メンバ関数も呼び出せる
から」
『それが2行目ってこ……あ! この DoModal() ってメンバ関数、どっか
で見た! えっとね……』
「ヒント、ついさっきだよ」
『ついさっきって、MSDNの……そう! CDialog のメンバ関数!』
「そ。 CDialog::DoModal() は、ダイアログを表示するメンバ関数」
『あ、こういうふうに呼び出せば、CDialog の、その〈ダイアログを操作す
る機能〉っていうのが使えるってことなのね』
「そういうことになるかな。変数を通してメンバ関数を呼び出すときには、
ピリオド( . )のあとにメンバ関数、で呼べるから」
『ってことは、 CCalcDlg::OnBEqual() なんかもこんなふうに呼び出せるの
ね』
「ギク、実は呼び出せないんだよ」
『え〜なんで!?』
「それはまた今度。……ほら、それって〈ボタンを押したとき〉用でしょ、
だからむやみやたらに呼び出せないようになってるわけ」
『ふーん』
「気を取り直して、ビルドして実行してみましょう」
『あ、うん。ビルドして実行、【=】ボタンを押すと……あ! 同じダイア
ログがもいっこできた!』
「再びまとめ!」
『はい!』
「プログラムを作るってことは、CCalcDlg クラスみたいなカスタマイズク
ラスを作ること」
『うんうん』
「作ったら、そのクラス型の変数を作って、メンバ関数を呼び出す!」
『あとは関数を呼び合って、プログラムが成り立つ!』
「そういうことです! じゃ、それを確認するために、 Calc.cpp ファイル
を開いてみて」
『あれ? まだ開いたことないファイルだね。えっと、〈ワークスペース〉
開いて、【FileView】の……』
「【Source Files】の中」
『あ、【.cpp】はそっちなんだ。でその中の【Calc.cpp】を開いて……』
「その中に CCalcApp::InitInstance() ってメンバ関数あるでしょ」
『うん、あるね』
「その真ん中あたり……」
BOOL CCalcApp::InitInstance()
{
// 略。
CCalcDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
// 略。
}
『あ!! CCalcDlg dlg; って、CCalcDlg 型の変数を作るってことで、しか
も dlg.DoModal() って……』
「どう? これで〈クラス作って変数作ってメンバ関数を呼ぶ〉ってことが
分かったでしょ?」
『……じゃあこの CCalcApp::InitInstance() ってメンバ関数は?』
「これは〈アプリが実行されたときに呼ばれる関数〉。CCalcDlg::OnBEqual()
みたいに、他から呼び出される関数ってことだね。じゃ、次の質問」
『CCalcApp ってどんなクラス?』
「それは Calc.h を見れば分かるでしょ?」
『そ、そういえばそうね……【FileView】の【Header Files】から【Calc.h】
を開いて……』
class CCalcApp : public CWinApp
{
// 略。
};
『激! イヤな予感……』
「だから言ったでしょ、カスタマイズクラスを作ることが、プログラムを作
ることだって」
『ってことはやっぱ、CWinApp もMFCのクラスなのね……』
「そういうこと。CWinApp はアプリの中心になるクラス」
『……最後の悪あがき、CCalcApp の変数ってどこ?』
「さっきの CCalcApp::InitInstance() のすぐ上」
『へ?』
/////////////////////////////////////////////////////////////////////////////
// 唯一の CCalcApp オブジェクト
CCalcApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CCalcApp クラスの初期化
BOOL CCalcApp::InitInstance()
{
// 略。
『あれ? 関数の外でも変数って作れるの?』
「一応ね。この CCalcApp 型の変数が、アプリの情報を持ってるわけ」
『で、アプリを実行すると CCalcApp::InitInstance() が呼び出される』
「中で CCalcDlg 型の変数が作られて」
『 DoModal() ってメンバ関数が呼ばれてダイアログが表示される、か』
「これが〈プログラム〉の全体の流れってとこかな。さらに付け加えると」
『なに?』
「実行して、左上のアイコンを左クリックしてみて」
『はーい。えっと、アイコンをクリック……もしかして〈Calc のバージョ
ン情報〉のこと?』
「そう、それクリックして」
『はーい。あ、ダイアログ出た! ってもしかしてこれも……』
「大当たり! CalcDlg.cpp の上の方見てみて」
『えっと、さっきのウィンドウに戻って……あ!』
class CAboutDlg : public CDialog
{
// 略。
};
『あれ? なんでヘッダーファイルの方に書いてないの?』
「これはちょっとルール違反かな。ま、こういうこともできるってことで、
真似しないようにね」
『はーい。で、このクラスの変数はどこで作ってるの?』
「 CCalcDlg::OnSysCommand() の中」
void CCalcDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
『こっちも同じね』
「ちなみに CCalcDlg::OnSysCommand() は、さっきのメニューコマンドを選
択したときに呼び出される関数」
『はい、今日のまとめ、MFCのクラスを継承して、新しいクラス作って、
そのクラスの変数作って、メンバ関数呼び出す、ね?』
「そういうこと」
/*
Preview Next Story!
*/
「クラスって言えば、このまえ同窓会の誘いが来てたなー」
『ヒドイわヒドイわ!!』
「な、なに?」
『あたしが学校行ったことないの知っててそんな楽しそうな話題を!!』
「わ! ご、ゴメン……」
『というわけで次回』
< Version 3.2 ハンドルとメンバ変数 >
「につづく!!」
『罰として学校ゴッコを命ずる!』
「学校……ごっこ?(どきどき)」
『きーん、こーん、はい水希ちゃん!!』
「え……かーん、こーん……」
『よくできました!』
「???」