1 / 32

オブジェクト指向プログラミングの概要     ー オブジェクト指向の考え方を理解する -

3章  C++ プログラムの構成   2001年11月更新. オブジェクト指向プログラミングの概要     ー オブジェクト指向の考え方を理解する -. オブジェクト指向 ( Object Oriented Concept) とは?. ― ソフトウェアの構成を      もの( Object) を中心に考えるアプローチ方法 ―. 《 オブジェクト(もの) 》.  情報を記録する 変数. 他のオブジェクト. 変数を操作する固有 の メソッド. 機能. 他のオブジェクトと 交信する メソッド. メッセージ のやりとり. Smalltalk,C++,Java など.

shaman
Download Presentation

オブジェクト指向プログラミングの概要     ー オブジェクト指向の考え方を理解する -

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 3章 C++プログラムの構成  2001年11月更新 オブジェクト指向プログラミングの概要     ー オブジェクト指向の考え方を理解する -

  2. オブジェクト指向(Object Oriented Concept)とは? ― ソフトウェアの構成を      もの(Object)を中心に考えるアプローチ方法 ― 《 オブジェクト(もの) 》  情報を記録する変数 他のオブジェクト 変数を操作する固有 のメソッド 機能 他のオブジェクトと 交信するメソッド メッセージのやりとり Smalltalk,C++,Javaなど

  3.  クラス 学生 ― 変数名 ― 学籍番号 氏名 年齢 ― メソッド名 ― 学ぶ 本を読む 食べる 会話をする インスタンス  学生2 インスタンス  学生n オブジェクト指向のいくつかの特徴 •  クラス&インスタンス インスタンス毎に 異なる部分 共通する 変数名 ― 変数 ― 学籍番号= データ値1 氏名   = データ値2 年齢   = データ値3 ― メソッド ― 学ぶ 本を読む 食べる 会話をする データと機能(メソッドと呼ぶ)が一緒になったオブジェクト (=インスタンス)を中心に考える. ② 逆にインスタンスは  クラスから生成する    ものと考える 共通する変数名 共通する メソッド名 共通するメソッド名   (メンバ関数名) インスタンス  学生1 インスタンス 学生4 ①共通するもの(変数名,メソッド名)  はクラスにまとめ,それを利用する

  4. (2) イベントの発生とメッセージの送受信(2) イベントの発生とメッセージの送受信 イベント(マウスクリックやメニュ―選択,タイマーのタイムアウト等)が生じるとメッセージが発生する.何をやるかは,メッセージを受信したオブジェクト側に記述する. ― 変数群― 身長=データ値1 体重=データ値2 体温=データ値3 学籍番号=データ値4 氏名= データ値5 年齢= データ値6 ― メソッド群 ― 歩く 走る 食べる   オブジェクトn 他のオブジェクト オブジェクトa イベント1の発生 メッセージ「走る」 他のオブジェクトへの メッセージ 他のオブジェクトへ メッセージを送信するイベント 一致するメソッドが あるば起動する メッセージを受信したとき,やるべき操作を                  プログラムする

  5.  クラス 会社員 ― 属性名 ― 社員番号 氏名 ― メソッド名 ― 仕事をする 打合せる  クラス 人間 ― 変数名 ― 身長 体重 体温 ― メソッド名 ― 歩く 走る 食べる 会話をする  クラス 学生 ― 属性名 ― 学籍番号 氏名 年齢 ― メソッド名 ― 学ぶ 本を読む (3) 変数とメソッドの継承性 いろいろなクラスに共通する変数やメソッドは階層構造の上位クラスのもたせ, 下位クラスはそこから自動的に変数名やメソッド名を引継ぐことができる. 学生の1つのインスタンス(オブジェクト) がもつ変数と利用可能なメソッド ― 変数群 ― 身長=データ値1 体重=データ値2 体温=データ値3 学籍番号=データ値4 氏名= データ値5 年齢= データ値6 ― メソッド群 ― 歩く 走る 食べる 会話をする 学ぶ 本を読む 「クラス 学生」のインスタンスを生成 「クラス 人間」から 継承してきた変数  継承する (上位クラスから変数名  やメソッド名を引き継ぐ) 「クラス 人間」から継承してきたメソッド

  6.  クラス 人間 ― 変数名 ― 身長 体重 体温 ― メソッド名 ― 歩く 走る 食べる 会話をする (4) 多相性 メソッドは上位クラスと継承関係をもった下位クラスで再定義できる. ② 同じメッセージで,受信側のオブジェクト毎に 操作内容を変えることができる. aInstance メッセージ「会話する」 生成 代入 メッセージ「会話する」 a人間 代入 生成  クラス 学生 ― 変数名 ― 学籍番号 氏名 年齢 ― メソッド名 ― 学ぶ 本を読む 会話をする  // 英会話を意味する メッセージ「会話する」 a学生 継承 ① 再定義できる.

  7. 補足 オブジェクト指向によるソフトウェア開発の利点 クラスやオブジェクト間の関連がソフトウェア開発の分析設計段階できると, 後はそれぞれのオブジェクトのメソッドを詳細化して行くだけでよい。        (必要に応じて一時的な変数やメソッドを追加する) 《 クラス図 》 ペット 愛称 お手 お座 ・・・ 《 オブジェクト図 》 0..* 1: 指示を出す 1 人 氏名 指示を出す   :人 2: お座り 1 メソッドを次々と追加 3: お手   :ペット メソッド内容を段階的に詳細化 0..2 家

  8. Visual Smalltalk Workbench 3.11にみる        オブジェクト指向プログラミングの基本概念 プログラムはオブジェクト(=インスタンス)とイベント,メッセージだけから構成され                           それらを図示しながらプログラムを作る. ②イベントが起こったとき,オブジェクトに送るべきメッセージを指定する. 1つのアプリケーション Windowの 1つのインスタンス ②メッセージ 部品クラス ライブラリ Menuの1つ のインスタンス MenuItemの1つ のインスタンス DialogBoxの1つ のインスタンス イベント ③Openメッセージを受信して,何をやるか はWindowクラス側に記述されている ①インスタンスを   生成する ③Openメッセージを受信して,何をやるか はWindowクラス側に記述されている

  9. MS Visual Studioを利用したMS Visual Studioを利用した  C++プログラミングの方法

  10. オブジェクト指向プログラミングはどのような手順で行うか スパイラル的に繰返し設計しプログラミングしてゆく 第2段階:メッセージの決定 クラス間でやり取りされるメッセージを決める 第3段階:具体的な手順の決定 オブジェクトがメッセージを受取って何をやるかを決める オブジェクトp 相互作用 オブジェクトs オブジェクトq オブジェクトr クラスA 第1段階:クラスの決定 必要なクラスとクラス間の関連や継承関係等を決める クラスB クラスC

  11. 第1段階:クラスの決定 必要なクラスとクラス間の関連や継承関係等を決める 《 一般的なクラス構成の考え方:MVCモデル 》 アプリケーションに共通  するデータを格納する機能    をもったクラス  (Modelクラス) Microsoft VC++では, Documentクラスと呼んでいる 互いに役割を分担した3つのクラス群が協調する形で,1つのプログラムを構成する 入出力表示の機能   をもったクラス  (Viewクラス)  イベントの発生の監視や 実行制御する機能をもった クラス (Controllerクラス) Microsoft VC++では,Controllerクラスの機能は Viewクラスに一緒になっている

  12. クラス CView クラス CFameWnd クラス CDocument  クラス Cアプリケーション名App ◆ “MFC AppWizard”を使うと,アプリケーションプログラムを構成する         基本的な4つのクラスを自動的に生成してくれる    (メーンフレーム画面を作る代表的なアプリケーションのとき)  クラス Cアプリケーション名View 継承 必要に応じて関連をもつ メインフレームウインドウ内のクライアント領域を管理するクラス 継承  クラス Cアプリケーション名Doc アプリケーションで共通して用いるデータを格納しておくModelクラスに相当する 継承  クラス CMainFrm メインフレームウインドウ(メニューバーを含む)の制御を担当するクラス クラス CWinApp 継承 アプリケーション全体の制御を担当するクラス.最初に起動する.

  13. ◆ 4つのクラスから生成されたインスタンスは,Windowシステムが監視し◆ 4つのクラスから生成されたインスタンスは,Windowシステムが監視し   ているイベントが発生すると送られてくるメッセージを拾って,いろいろな   処理を行う. インスタンスを生成する プログラムの世界 表示された世界 CアプリケーションViewの    インスタンス メインフレーム画面 class CアプリケーションView メニューバー メニューアイテム1 メニューアイテム2 対応 クライアント領域 インスタンスを生成する イベントメッセージの転送 対応 class CMainFrame CMainFrameの    インスタンス インスタンスの生成メッセージ イベントメッセージ インスタンスを生成する class CアプリケーションApp アプリケーションAppクラス のインスタンス “theApp” 最初に実行 いろいろなイベント(マウスクリック,ボタンクリック,タイマー等)

  14. オブジェクト指向プログラミングはどのように行うか クラスは,どこに,どのようにして書くのか ◆ クラスはヘダーファイルとCPPファイルに分けて記述する(1) クラスの変数名やメンバ関数の      プロトタイプ宣言 アプリケーション名View.h class CアプリケーションView アプリケーション名View.cpp クラスのメンバ関数の   具体的な内容を定義 MainFrm.h class CMainFrame MainFrm.cpp アプリケーション名.h class CアプリケーションApp アプリケーション名.cpp

  15. ◆ ヘダーファイルとCPPファイルに記述される内容(詳しい意味は後述)◆ ヘダーファイルとCPPファイルに記述される内容(詳しい意味は後述)    プロトタイプ宣言部 Classクラス名 {     ・変数名(メンバ変数名と呼ぶ)群の定義     ・メソッド名(メンバ関数名と呼ぶ)群のプロトタイプ宣言     ・イベントハンドラ関数名群のプロトタイプ宣言 (イベント発生のメッセージを拾って,何らかの処理を行うメンバ関数) DECLARE_MESSAGE_MAP()  // イベントハンドラ関数があるとき記述する   } ヘダーファイル(XXX.h) 取り込む #include “XXX.h” 各種メンバ関数の具体的な定義部 CPPファイル(XXX.cpp) BEGIN_MESSAGE_MAP    イベントメッセージを拾い起動するイベントハンドラ関数の対応付けマクロ END_MESSAGE_MAP クラス名::メンバ関数名 // クラスがもつ固有の処理内容の定義 { } メンバ関数(=メソッド)とはクラスに含まれる(=クラスのメンバ)であることを意味する. クラス名::イベントハンドラ関数名   // これもメンバ関数の一種である /* イベント メッセージを拾って行うべき処理の内容を定義する */ { }

  16. 上位クラス名 継承性の制御(後で解説)  CDialog CCMDlg 新しいクラスはどのように記述するか classCCMDlg : public CDialog { public: CCMDlg(CWnd* pParent = NULL); // 標準のコンストラクタ enum { IDD = IDD_CM_DIALOG }; CString m_input; CString m_output; protected: virtual void DoDataExchange(CDataExchange* pDX);     HICON m_hIcon; // 生成されたメッセージ マップ関数 //{{AFX_MSG(CCMDlg) virtual BOOL OnInitDialog(); afx_msg void OnSysCommand(UINT nID, LPARAM lParam); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButtonA(); afx_msg void OnButtonABar(); afx_msg void OnButtonB(); afx_msg void OnButtonBBar(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; OKボタンを押すと自動的にクラスCMDlgのプロトタイプ宣言(ヘダーファイル)とハンドラ関数ファイル(cpp)が Visual Studioによって自動的に生成される 上位クラスの意味 リソースエディタで例えば”IDD_DIALOG2” のリソースIDをもつダイアログを作成し, メニュー“挿入”から“クラスの新規作成” を選ぶとこのようなダイアログが表示される

  17. 【補足】 クラスからインスタンスを作成したとき,メンバ変数を初期化したいとき【補足】 クラスからインスタンスを作成したとき,メンバ変数を初期化したいとき          メンバ変数を初期化する特殊なメンバ関数=コンストラクタ クラス名とメンバ関数名が同じ 初期化するとき,初期値をパラメータで指定してもらうときもある CSpeedDlg::CSpeedDlg(CWnd* pParent /*=NULL*/) : CDialog(CSpeedDlg::IDD, pParent) { m_resist = 0.0f; m_speedX = 0.0f; m_speedY = 0.0f; m_speedZ = 0.0f; } クラスCSPeedDlgのインスタンスを作成するとき, CSPeedDlgで定義されたメンバ変数の値を初期化する.  CDialog CSpeedDlgはCDialogクラスからもメンバ変数を継承する. そこでCDialogのメンバ変数の初期化は,CDialogの初期化CDialogのコンストラクタを呼び出して任せる  CSpeedDlg

  18. 第2段階:メッセージの決定    イベントメッセージを拾って起動すべきハンドラ関数名やクラス間         (あるいはクラス内)で呼出しあうメンバ関数名を決める. #include “XXX.h” 各種メンバ関数の具体的な定義部 イベントが発生したとき送られてくるイベントメッセージ BEGIN_MESSAGE_MAP    イベントメッセージを拾い起動するイベントハンドラ関数の対応付けマクロ END_MESSAGE_MAP このクラスで拾うイベントメッセージがあれば,そのイベントメッセージに対応するイベントハンドラ関数を呼出す クラス名::メンバ関数名 // クラス固有のがもついろいろな処理内容の定義 { } クラス名::イベントハンドラ関数名1 // これもメンバ関数の一種である /* 送られてきた イベントメッセージを拾って,そのイベントに対応する                                   処理内容を定義する */ {     他のメンバ関数の呼び出し;     クラス名::メンバ関数名;    // 他のクラスのメンバ関数の呼び出し } 必要に応じて呼出す

  19. イベントメッセージ名 リソースID ON_ COMMAND + IDC_SETTIMER ◆ GUIを構成する要素(オブジェクト)には,すべてリソースIDが付いており,実行時    にリソースで定義したリーソスにイベント(例えばクリック)が発生すると,リソースID    をもったイベントメッセージがWindowsシステムから送られてくる リソースIDは, リソースエディタでそれぞれの リソースオブジェクトに対して名付けた名前

  20. イベントメッセージ名の切り分けマクロ名 ◆ インスタンスがイベントメッセージを受取ったとき,    どのイベントハンドラ関数を呼び出すかはMESSAGE_MAPで対応つけている (※MESSAGE_MAPはVC++が自動的に作成する) CPPファイル(XXX.cpp) #include “XXX.h” BEGIN_MESSAGE_MAP // メベントメッセージを拾って起動するイベントハンドラ関数の対応付け ON_COMMAND ( IDC_KILLTIMER, OnKillTimer ) END_MESSAGE_MAP リソースID 呼び出すイベントハンドラ関数名 イベントメッセージON_COMMAND_IDC_KILLTIMERが来るとOnKillTime関数を呼出す クラス名::メンバ関数名       // 関数の具体的な内容を定義 { } クラス名:: OnKillTimer// イベントハンドラ関数の具体的な内容を定義 { } クラス名::OnリソースID_n  // イベントハンドラ関数の具体的な内容を定義 { }

  21. 構成上のリンクにしたがって転送する イベントメッセージ ON_COMMAND + オブジェクトID WM_コマンド名 + パラメータ 操作イベント ◆イベントメッセージは,次々と転送される途中で各クラスのメッセージマップに           同じものがあれば拾われ,対応するイベントハンドラ関数を起動する メッセージマップを見る CTestDialogのインスタンス class CTestDialog (ダイログボックスに対応) メッセージマップに拾うべきイメントメッセージ名 があれば,イベントハンドラ関数を起動 構成上のリンク メッセージマップを調べる順番 メッセージマップを見る class CTestView CTestViewのインスタンス (クライアント領域に対応) メッセージマップに拾うべきイメントメッセージ名 があれば,イベントハンドラ関数を起動 構成上のリンク class CMainFrame メッセージマップを見る CMainFrameのインスタンス (メイン画面に対応) メッセージマップに拾うべきイメントメッセージ名 があれば,イベントハンドラ関数を起動 メッセージマップを見る class CTestンApp    CTestAppの    インスタンス theApp メッセージマップに拾うべきイメントメッセージ名 があれば,イベントハンドラ関数を起動 メインフレーム画面 メニューバー メニューアイテム1 メニューアイテム2 ダイアログボックス メニュー ボタン1 フィールド1 ボタン2 Windows システム

  22. ◆ ClassWizardを使うと,クラスで拾うべきイベントメッセージ(=◆ ClassWizardを使うと,クラスで拾うべきイベントメッセージ(=      イベントの種類とイベントが発生したリソースID)と呼出すイベントハンドラ      関数名の指定が,半自動的できる. どこのクラスで拾うかの指定 拾うべきイベントの種類 イベントが発生したリソースID イベントメッセージを拾ったとき実行するハンドラ関数名 イベントメッセージ名

  23. 第3段階:具体的な処理手順の決定 インスタンスがイベントメッセージを受取ったり, 他から呼出さ   れたとき 何をやるかの具体的な内容を決める CPPファイル(XXX.cpp) #include “XXX.h” BEGIN_MESSAGE_MAP /END_MESSAGE_MAP クラス名::メンバ関数名       // 関数の具体的な内容を定義 { } クラス名:: OnKillTimer// イベントハンドラ関数の具体的な内容を定義 { } クラス名::OnリソースID_n  // イベントハンドラ関数の具体的な内容を定義 { }

  24. ◆ メンバ関数内で新たにクラス(例えばDialog)のインスタンスを◆ メンバ関数内で新たにクラス(例えばDialog)のインスタンスを                      作りたいとき,どのように記述するか. #include “CMDlg.h”// <= CMDlgの宣言部分をあらかじめ読み込み float x;// <= float型変数xのメモリ領域を確保する CCMDlg  dlg;/* <= クラスCCMDlgからインスタンスdlgを作成し,                   ダイアログのメモリ領域を確保する   */ dlg.DoModal();// ダイアログを実際に表示するメンバ関数を呼び出す. Dialogクラスを作成したときのクラス情報を格納したファイル名 上位クラスの意味

  25. ◆ インスタンがもつ変数,メンバ関数へのアクセス方法◆ インスタンがもつ変数,メンバ関数へのアクセス方法 インスタンス名の後にドット(.)をつけて,変数名,メソッド名を記述する  《 インスタンス g がもつ   変数とメンバ関数 》 ― 変数群 ― float m_resist; float m_speedX; float m_speedY; float  m_speedZ; ― メンバ関数群 ― void addVelocuty(); void subtVelocity(); 変数のアクセス方法 g.m_speedX = 10.0; // 構造体のアクセスと同じ メンバ関数のアクセス方法 g.addVelocity( );//  構造体のアクセスと同じ

  26. 【上級編】 --- プログラムの中で必要に応じて,動的にインスタンスを生成したいとき.--- CMsgDlg * pDlg;/* <= 作成すべきクラスCMsgDlgのインスタンスへの                          ポインタを格納しておくメモリ領域を確保する */ : pDlg = new CMsgDlg();/* <=  クラスCMsgDlgのインスタンスを作成し, そのインスタンスへのポインタをpDlgに格納する.*/ pDlg-> DoModal();     /* メンバ関数の呼び出し  */

  27. ◆ ClassWizardを用いると,GUIを構成するオブジェクトのリソースIDと◆ ClassWizardを用いると,GUIを構成するオブジェクトのリソースIDと       プログラム中のクラス内変数名とを簡単に対応されることができる プログラムの世界 GUIを構成するオブジェクトの世界 class CSpeedDlg : public CDialog {   public: CSpeedDlg(CWnd* pParent = NULL); enum { IDD = IDD_DIALOG1 }; float m_speedX; float m_speedY; float m_speedZ;         float m_resist; リソースID: IDC_SPEEDX リソースID: IDC_SPEEDY リソースID: IDC_SPEEDZ リソースID: IDC_RESIST

  28. VC++でプログラミングするときの一般的な注意VC++でプログラミングするときの一般的な注意 ◆ ヘルパー(お助け)関数 C++のメンバ関数の中でも,Cの関数を補助的に使える ヘルパー関数 C言語関数の定義 ※(注) 識別子の有効範囲が異なるため           この中ではクラスのメンバ変数やメンバ関数は           使用できない. クラス名::メンバ関数名       // 関数の具体的な内容の定義 {       関数の呼び出し(...); }

  29. 完全に外部から隠される メンバ変数群 メンバ変数群 メンバ変数群 メンバ変数群 メンバ変数群 メンバ変数群 メンバ関数群 メンバ関数群 メンバ関数群 メンバ関数群 メンバ関数群 メンバ関数群 継承によるアクセス 外部からのアクセス 継承によるアクセス 外部からのアクセス 継承によるアクセス クラス外部からのアクセス クラス外部からのアクセス ◆ 呼出し可能なメンバ関数と継承性を利用して上位クラスのアクセス           を制御する Private,Protected,Public Class A 上位のクラス Private Class B Private Protected Protected クラス内部でのみ アクセスは可 Public Public

  30. InitApplication関数 ①theAppのもつ アプリケーションの初期化 theAppに対して 1: InitApplication関数, 2: InitInstance関数, 3: Run関数の呼出し Run関数 ③ theAppのもつイベントメッセージを取出す無限ループ // 唯一の Cクラス名App オブジェクト Cクラス名App theApp; InitInstance関数 ② theAppのもつメインフレーム画面やダイログボックスの作成と初期化 CCMAppからインスタンスを生成し, theAppとする. 3 オブジェクト指向プログラミングの仕掛けを理解しよう 【補足1】 C++プログラムの基本的な動作手順 class CWinApp WinMain(・・・・) 上位クラスのメンバ関数を継承 アプリケーション・オブジェクト インスタンス theApp class Cクラス名App

  31. インスタンスを生成する CTestViewのインスタンス メインフレーム画面 対応 クライアント領域 インスタンスを生成する 対応 CMainFrameのインスタンス CWinTestのInitInstance 関数内からインスタンス生成関数   (コンストラクタ)を呼出す 【補足2】メインフレーム画面を用いるときのInitInstance関数の処理 class CView 上位クラスのメンバ関数を継承 class CTestView class CMainFrame WinMain 1.TheAppの初期化処理を行うためCwinAppの InitApplication( )関数を呼出す 2.CWinTestのInitInstance関数を呼出す 3.メッセージキューからイベントメッセージ の取出しと無限ループを形成するCwinAppの Run( )関数を呼出す アプリケーションクラス (ここではCWinTest)のインスタンス theApp

  32. インスタンス生成呼出しを受け,CCMDialogのインスタンスを生成するインスタンス生成呼出しを受け,CCMDialogのインスタンスを生成する ダイアログボックス Cクラス名Dialogのインスタンス CWinTestのInitInstance 関数内からインスタンス生成   関数 (コンストラクタ)を呼出す 対応 【補足3】 ダイアログボックスを用いるときのInitInstance関数の処理 class CDialog 上位クラスのメンバ関数を継承 class Cクラス名Dialog WinMain 1.TheAppの初期化処理を行うためCwinAppの InitApplication( )関数を呼出す 2.CWinTestのInitInstance関数を呼出す 3.メッセージキューからイベントメッセージ の取出しと無限ループを形成するCwinAppの Run( )関数を呼出す アプリケーションクラス (ここではCWinTest)のインスタンス theApp

More Related