プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース

Slides:



Advertisements
Similar presentations
1 C++ における OOP を用いた 書き方講座 H 山崎貴英. 2 今回の内容 OOP とは? C++ の超基礎 注釈 書いてあるコードはすべて一部抜粋。 コピペだと動かないよ!
Advertisements

オブジェクト指向 言語 論 第八回 知能情報学部 新田直也. 多相性(最も単純な例) class A { void m() { System.out.println( “ this is class A ” ); } } class A1 extends A { void m() { System.out.println(
ソフトウェア工学 知能情報学部 新田直也. オブジェクト指向パラダイムと は  オブジェクト指向言語の発展に伴って形成され てきたソフトウェア開発上の概念.オブジェク ト指向分析,オブジェクト指向設計など,プロ グラミング以外の工程でも用いられる.  ソフトウェアを処理や関数ではなくオブジェク.
6.4継承とメソッド 6.5継承とコンストラクタ 11月28日 時田 陽一
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
Generic programming と STL
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
1.1 C/C++言語 Hello.ccを作りコンパイルしてa.outを作り出し実行する
~手続き指向からオブジェクト指向へ(Ⅰ)~
プログラミング基礎I(再) 山元進.
C#によるWindowsFormApplication入門
アルゴリズムとデータ構造1 2007年6月12日
構造体.
社会人学習講座 「Javaプログラミング概論」
インタラクティブ・ゲーム制作 <プログラミングコース>
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
インタラクティブ・ゲーム制作 <プログラミングコース>
プログラミング演習3 第2回 GUIの復習.
補足説明.
コンパイラの解析 (2) GCJのデータ構造 - 1.
ソフトウェア工学 知能情報学部 新田直也.
プロジェクト演習Ⅱ インタラクティブゲーム制作 イントロダクション2
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
アルゴリズムとプログラミング (Algorithms and Programming)
インタラクティブ・ゲーム制作 <プログラミングコース>
オブジェクト指向 プログラミング 第十一回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第十三回 知能情報学部 新田直也.
暗黙的に型付けされる構造体の Java言語への導入
ローカル変数とグローバル変数 ローカル変数  定義された関数内だけで使用できる変数 グローバル変数 プログラム全体で使用できる変数.
プログラミング 4 記憶の割り付け.
プログラミング演習3 第2回 GUIの復習.
インタラクティブ・ゲーム制作 <プログラミングコース>
C#言語ソースプログラムの原型 C言語 C#言語 Hello World! Hello Students! オマジナイ! 適当なクラス名
Java8について 2014/03/07.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
オブジェクト指向言語論 第八回 知能情報学部 新田直也.
インタラクティブ・ゲーム制作 プログラミングコース 補足資料
プロジェクト演習Ⅱ インタラクティブゲーム制作
オブジェクト指向 プログラミング 第十ニ回 知能情報学部 新田直也.
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
オブジェクト指向言語論 第十一回 知能情報学部 新田直也.
プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース
第1章 いよいよプログラミング!! ~文章の表示 printf~
アルゴリズムとプログラミング (Algorithms and Programming)
オブジェクト指向プログラミング クラス 継承
プログラミング言語論 第十三回 理工学部 情報システム工学科 新田直也.
ソフトウェア工学 知能情報学部 新田直也.
プロジェクト演習Ⅳ・Ⅵ インタラクティブゲーム制作
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
C#プログラミング実習 第3回.
サブゼミ第7回 実装編① オブジェクト型とキャスト.
11.1 標準ライブラリ関数 11.2 関数呼び出しのオーバーヘッド 11.3 大域変数 11.4 プロトタイプ宣言 11.5 関数引数
第5回 プログラミングⅡ 第5回
JAVA入門⑥ クラスとインスタンス.
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第七回 知能情報学部 新田直也.
Javaとは Javaとはオブジェクト指向言語でJava VM(Java仮想マシン)と呼ばれるプログラム上で動作します。
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
情報処理Ⅱ 2005年11月25日(金).
プログラミング入門2 第5回 配列 変数宣言、初期化について
オブジェクト指向 プログラミング 第六回 知能情報学部 新田直也.
プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース
プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース
オブジェクト指向言語論 第九回 知能情報学部 新田直也.
オブジェクト指向言語論 第十回 知能情報学部 新田直也.
計算技術研究会 第5回 C言語勉強会 関数(function)を使う
C言語講座第5回 2017 構造体.
計算機プログラミングI 第10回 2002年12月19日(木) メソッドの再定義と動的結合 クイズ メソッドの再定義 (オーバーライド)
Presentation transcript:

プロジェクト演習III,V <インタラクティブ・ゲーム制作> プログラミングコース 第7回 継承の使い方:C++編

今日の内容 先週のコードで継承が出てきた 今週のOOPでも継承が出てきた じゃあやらねばなりますまい! C++での継承の書き方 メリットその1:差分プログラミング コンストラクタ、デストラクタの注意点 メリットその2:多態性(ポリモフィズム) オーバーライド、仮想関数

でも、理解できないものを 無理に使う必要は無い C++は懐の広い言語なので、全部の言語仕様を使い切らずに、理解の出来る範疇で開発してもよい というか、言語仕様を完璧に把握してる人なんて……いるのだろうか? 元々C++はC言語に付け足して出来ているので、様々な時代の概念が混在している マルチパラダイム言語と呼ばれたり 色んな考え方をまぜこぜにしてもOK

とはいえ 出来ることの幅が広がった方が、後々の選択肢が増えたり、楽できるのも事実 一気に取り込まず、別プロジェクトで 実験してから順次導入していこう

継承が便利な時:その1 差分プログラミング プラグちゃんに改造パーツを取り付けた、 グレートプラグちゃんを作りたい 基本構造はプラグちゃんのままなので、 その部分はうまいこと使い回したい でもコピペはヤダ!後でプラグちゃんを修正した時にコピペ先も直さないといけないから プラグちゃんを継承し、 グレートプラグちゃんを作る

C++での継承の書き方 // 継承したいクラス(基底クラス)のヘッダをインクルードする #include “PlugChan.h” // extendsキーワードではなく、コロン(:)を挟むだけ // public以外のキーワードも指定できるが、基本的にpublicのみ class GreatPlugChan : public PlugChan { // ここにGreatPlugChanとして付け足したいメンバを宣言 }; // cpp側は、普通にこのヘッダをインクルードして実装すればよい

コンストラクタはどうなる? 基本的には継承元 (基底クラス)のコンストラクタは勝手に 呼んでくれる 継承先(派生クラス)で新たにコンストラクタを作ってもよい ただし、引数付きのコンストラクタを使う場合は、継承先(派生クラス)の コンストラクタで明示的に呼ぶ必要がある // 基底クラスParentのコンストラクタが整数値を取る場合 #include “Parent.h” Child::Child(int hoge) : Parent(hoge) // これで呼べる { } // メンバ変数の初期化リストと同じような書き方なので、混同に注意!

デストラクタは? コンストラクタとは逆に、派生側から 順番に呼ばれていく ただし、継承されることが前提となっているクラスでは、デストラクタの宣言にvirtualを付けよう 付けておかないと、後々壮絶なメモリリークをかますおそれがあるので

差分プログラミングの他の例 既にあるクラスへの付け足しや書き換え 共通の処理や構造をまとめておき、 状況に合わせて必要なものを付け足す fk_Modelを継承して、ブロック専用モデルや 球専用モデルを作るなど(fkut_???Model) 共通の処理や構造をまとめておき、 状況に合わせて必要なものを付け足す fkut_AppBaseを継承してプログラムを作成 このクラス名から「ベースプログラム」という 名称が変に定着してしまったのかも

継承が便利な時:その2 ポリモフィズム(多態性) 共通の基底クラスから派生したクラスは、基底クラス型のポインタでまとめて管理できる PlugChan *plugs[2]; plugs[0] = new PlugChan(); plugs[1] = new GreatPlugChan(); 基底クラスでうまく共通項を括りだしておくと、派生クラスのバリエーションを効率良く管理できる

オーバーライドと仮想関数 基底型のポインタで管理している限り、基底型で宣言したメンバしか使えない しかし、基底型で宣言した関数を、 派生型で上書きしておくと、基底型の ポインタを通じて呼び出しても派生型で定義した処理を呼び出すことができる この関数上書きをオーバーライドと呼ぶ オーバーライドする関数は、仮想関数としてvirtualを付けておく必要がある

例えば 必殺技を起動する関数specialAttack()を作りたいとする プラグちゃんもグレートプラグちゃんも同じポインタの配列にしまっておきたい でもそれぞれのクラスで別々の処理が ちゃんと呼ばれるようにしたい

こうすればいいのだ class PlugChan { // 前後省略 virtual void specialAttack(void); }; ///////////////////////////////////// void PlugChan::specialAttack(void) { cout << “ろけっとぱ~んち!” << endl; } class GreatPlugChan : public PlugChan{ // 前後省略 void specialAttack(void); // オーバーライドする側はvirtual付けなくていい }; ///////////////////////////////////// void GreatPlugChan::specialAttack(void) { cout << “ウルトラスーパーエクセレントゴージャスろけっとぱ~んち!” << endl; }

俺の名前を呼んでみろ 前のようなスライドにした状態で、次のような呼び出しコードを書いてみる 自動的に処理が切り替わっているはず PlugChan *plugs[2]; plugs[0] = new PlugChan(); plugs[1] = new GreatPlugChan(); plugs[0]->specialAttack(); plugs[1]->specialAttack(); 自動的に処理が切り替わっているはず virtualを付け忘れると切り替わらない

派生クラスの関数から 基底クラスの関数を呼びたい! 基底クラス名::関数名()で呼べる 例えば、entry()関数をオーバーライドしたいが、基底クラスで用意しているものはそちらの処理に任せたい場合 void GreatPlugChan::entry(fkut_SimpleWindow &argWin) { PlugChan::entry(argWin); // この後に追加エントリー処理を書く }

補足:コンソール出力について coutやprintf()の表示は、プロジェクトの設定によって出たり出なかったりします プロジェクトのプロパティから右図の項目を確認して「コンソール」にしておきましょう

継承を使わなかったら どうなるか? 手間はかかるが何とかなる 差分プログラミングの代わりに ポリモフィズムの代わりに JavaとかC#だとそうは行かないが… 差分プログラミングの代わりに 毎回全部のメンバを書いたクラスをコピーして書き換えて使う ポリモフィズムの代わりに 想定される全ての機能、データを盛り込んだクラスを作り、オブジェクトごとにモードを切り替えて使う

継承を使うのは 必要に迫られてからでいい 無理して使うと設計がぐちゃぐちゃになって破綻する が、使えると色々スッキリするのは事実 同じコードをコピペしないで済む それぞれ別々の変数を用意しなくて済む スマートになりますよね 条件分岐がオブジェクト生成時だけで済む これが一番でかい