情報工学演習I 第13回 C++の演習5(仮想関数).

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

1 C++ における OOP を用いた 書き方講座 H 山崎貴英. 2 今回の内容 OOP とは? C++ の超基礎 注釈 書いてあるコードはすべて一部抜粋。 コピペだと動かないよ!
C++ 基礎. 目次 C++ とは? C++ におけるオブジェクト指向 課題 C++ とは? Cには足りなかったものが付与されて出来た物 具体的には、 情報の隠蔽(カプセル化) 共通の名前付け(関数のオーバーロード) 再利用の仕組み クラスの導入 など オブジェクト指向 C++ では大規模なプログラミングの.
オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第3回 配列(1) 情報・知能工学系 山本一公
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第5回 関数(1) 情報・知能工学系 山本一公
初年次セミナー 第8回 データの入力.
プログラミング演習II 2004年11月 30日(第6回) 理学部数学科・木村巌.
プログラミング演習(1組) 第7回
関数(1) 第11回 [6月29日、H.16(‘04)] 今日のメニュー 1 前回の課題 2 前回の宿題 3 いろいろな関数の演習 4 課題
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
1.1 C/C++言語 Hello.ccを作りコンパイルしてa.outを作り出し実行する
情報工学演習I 第10回 C++の演習2(クラスの継承).
数理情報工学演習第一C プログラミング演習 (第3回 ) 2014/04/21
プログラミング基礎I(再) 山元進.
配列(2) 第10回[平成15年6月26日(木)]:PN03-10.ppt 今日の内容 1 素数を求める(教科書の例):復習
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
プログラミング入門2 第10回 構造体 情報工学科 篠埜 功.
システムプログラミング 第5回 情報工学科 篠埜 功 ヒアドキュメント レポート課題 main関数の引数 usageメッセージ
プログラミング演習Ⅱ 第12回 文字列とポインタ(1)
プログラミング入門2 第1回 導入 情報工学科 篠埜 功.
プログラミング演習(2組) 第12回
プログラミング演習II 2004年10月19日(第1回) 理学部数学科・木村巌.
構造体.
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月10日、H.15(‘03)] 今日のメニュー 1 前回の課題の復習
配列の扱い、探索 有効範囲と記憶域期間 第12回 [7月6日、H.16(‘04)] 今日のメニュー 1 前回の課題の復習
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
プログラミングII 第 7 回 オブジェクトの配列 New, delete 参照 田向.
第6回独習Javaゼミ 第6章 セクション4~6 発表者 直江 宗紀.
補足説明.
岩村雅一 知能情報工学演習I 第8回(後半第2回) 岩村雅一
情報工学科 3年生対象 専門科目 システムプログラミング 第5回、第6回 ヒアドキュメント レポート課題 情報工学科 篠埜 功.
11.6 ランダムアクセスファイル 11.7 StreamTokenizerクラス
情報工学演習I 第12回 C++の演習4(インライン展開).
独習JAVA 6.8 コンストラクタの修飾子 6.9 メソッドの修飾子 6.10 ObjectクラスとClassクラス 11月28日(金)
オブジェクト指向 プログラミング 第二回 知能情報学部 新田直也.
プログラミング演習(2組) 第8回
情報・知能工学系 山本一公 プログラミング演習Ⅱ 第2回 ファイル処理 情報・知能工学系 山本一公
知能情報工学演習I 第9回( C言語第3回) 課題の回答
第9回関数Ⅰ (簡単な関数の定義と利用) 戻り値.
第7回 プログラミングⅡ 第7回
第11回 プログラミングⅡ 第11回
地域情報学 C言語プログラミング 第1回 導入、変数、型変換、printf関数 2016年11月11日
もっと詳しくArrayクラスについて調べるには → キーワード検索
岩村雅一 知能情報工学演習I 第12回(C言語第6回) 岩村雅一
オブジェクト・プログラミング 第8回.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
アルゴリズムとプログラミング (Algorithms and Programming)
東京工科大学 コンピュータサイエンス学部 担当 亀田弘之
知能情報工学演習I 第7回(後半第1回) 課題の回答
プログラミング言語論 第十一回 理工学部 情報システム工学科 新田直也.
プログラミング入門2 第13回、14回 総合演習 情報工学科 篠埜 功.
C#プログラミング実習 第3回.
第5回 プログラミングⅡ 第5回
東京工科大学 コンピュータサイエンス学部 担当 亀田弘之
JAVA入門⑥ クラスとインスタンス.
情報工学科 3年生対象 専門科目 システムプログラミング 第3回 makeコマンド 動的リンクライブラリ 情報工学科 篠埜 功.
岩村雅一 知能情報工学演習I 第12回(後半第6回) 岩村雅一
情報工学科 3年生対象 専門科目 システムプログラミング 第3回 makeコマンド 動的リンクライブラリ 情報工学科 篠埜 功.
演算子のオーバーロード.
情報処理Ⅱ 2005年11月25日(金).
プログラミング演習II 2003年11月19日(第6回) 木村巌.
プログラミング演習II 2003年12月10日(第7回) 木村巌.
プログラミング演習II 2004年11月 2日(第3回) 理学部数学科・木村巌.
プログラミング入門2 第5回 配列 変数宣言、初期化について
情報処理Ⅱ 小テスト 2005年2月1日(火).
値渡しと参照渡しについて.
printf・scanf・変数・四則演算
岩村雅一 知能情報工学演習I 第7回(後半第1回) 岩村雅一
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
Presentation transcript:

情報工学演習I 第13回 C++の演習5(仮想関数)

授業の予定(後半) # 月日 内容 担当者 7 11月13日 C言語の演習4 (ポインタの演算,列挙型) 内海 8 11月20日 9 11月27日 C++の演習1(クラス) 岩村 10 12月 4日 C++の演習2(クラスの継承) (代理:谷川) 11 12月11日 C++の演習3 (関数のオーバロード) 12 12月18日 C++の演習4(インライン展開) 13 1月 8日 C++の演習5(仮想関数) 14 1月15日 C++の演習課題 谷川 15 1月22日 総合演習

今日の内容 第10回演習課題の解説 派生クラスへのポインタ 仮想関数 純粋仮想関数

第10回演習課題の解説

第10回演習課題(1) 1. 以下の仕様を満たすプログラムを作れ 以下の仕様を満たすクラスを持つ 第9回演習課題(1)で作成したクラスを継承する 数学、理科、英語に加えて、国語の点数を保存すること ができる 合計4教科の点数を変更(上書き)できる関数と照会で きる関数がある 合計4教科の点数の平均を計算して返す関数がある 上記のクラスを用いて、2人分のデータ(名前、4教科の 点数)を順次コマンドラインから入力できる 全員分の情報を入力した後、一人ずつ名前と平均点を表示 する

第10回演習課題(1)の回答 ans10-1.cc ans9-1_another.ccのクラスScoreをベースクラスにした 気をつけるところ class Score データメンバのアクセス制限をprivatからprotectedに class Score2(Scoreを継承したクラス) 国語のスコアの宣言 国語のスコアの参照を返すメンバ関数 メンバ関数average()を上書き main関数 オブジェクトのクラスをScoreからScore2に 国語のスコアを入力して、オブジェクトに渡すルーチン main関数の変更箇所はこの2箇所だけ!

第10回演習課題(2) 2. 以下の様に分割コンパイルを実現せよ 第9回演習課題(2)で作成したプログラムを以下の3つ に分割する main関数を含むファイル クラスのヘッダファイル クラスのメンバ関数の定義を含むファイル コンパイルするコマンドをテキストファイルに書く 例: g++ -c ex5_main.cc g++ -c ex5_coordinate.cc g++ ex5_main.o ex5_coordinate.o ソースファイル(3つ)とコンパイルするコマンドを提出

第10回演習課題(2)の回答 ans9-2_another.ccを3分割した クラス定義:ans10-2_class.cc, ans10-2_class.h main関数:ans10-2_main.cc コンパイルの手順:ans10-2_command g++ -c ans10-2_class.cc g++ -c ans10-2_main.cc g++ ans10-2_class.o ans10-2_main.o

第10回演習課題(3) 3. 以下のプログラムを作成する 引数を2つ取る 1つはファイル名 もう一つは、キーワード ファイルの中にキーワードが何回出現するかを数える

strstr:文字列1から文字列2を検索する やり方はひとつではない 第10回演習課題(3)の回答 ans10-3.cc 方針 C言語の知識で実装 getlineコマンドでファイルからテキストを1行ずつ読み込 む strstrコマンドでテキスト(1行)ずつキーワードと比較 もしキーワードが見つからなければ、次の行へ もしキーワードが見つかれば、見つかった箇所までのテ キストを無視して再度比較する。これを見つからなくな るまで繰り返す。 getline:ファイルから1行読み込む (http://linuxjm.sourceforge.jp/html/LDP_man-pages/man3/getline.3.html) strstr:文字列1から文字列2を検索する (http://www9.plala.or.jp/sgwr-t/lib/strstr.html)

派生クラスへのポインタ

別クラスへのポインタ 通常は、あるクラスのポインタが異なるクラスのポ インタを指すことはできない

別クラスへのポインタ ex19_pointer_test.cc #include <iostream> using namespace std; class a {}; class b {}; int main () { a obja; // クラスaのオブジェクト b objb; // クラスbのオブジェクト a *pa = &obja; // クラスaのオブジェクトへのポインタ b *pb = &objb; // クラスbのオブジェクトへのポインタ // a *pa2 = &objb; // クラスaのポインタでクラスbを指す場合(エラーになる) }

派生クラスへのポインタ 基本クラスのポインタを使って派生クラスにアクセ スできる ただし、派生クラスにだけ存在するメンバ関数には アクセスできない 仮想関数を使うときに意味を持つ

派生クラスへのポインタ ex19_derive_pointer.cc #include <iostream> using namespace std; class base { // 基本クラス public: int i; base(int x) { // コンストラクタ(値の 代入) i = x; } void tasu(int x) { // 足す cout << i + x << endl; }; class deriv : public base { // 派生クラス public: deriv(int x) : base(x) {} // コンストラクタ が呼ばれれば、基本クラスのコンストラクタ で初期化 void kakeru(int x) { // 掛ける cout << i * x << endl; } };

派生クラスへのポインタ ex19_derive_pointer.cc 続き int main() { base *p; // クラスbaseへのポインタ base b(10); // クラスbaseのオブジェクト deriv d(10); // クラスderivのオブジェクト p = &b; // ポインタはクラスbaseのオブジェクトを指す p->tasu(5); // baseのtasu()を使用する p = &d; // ポインタはクラスderivのオブジェクトを指す p->tasu(5); // deriv1のtasu()を使用する(実際はbaseのtasu()を使用) // p->kakeru(5); // deriv1のkakeru()を使用する(エラーになる) return 0; }

仮想関数

仮想関数 基本クラス内で宣言され、派生クラス内で再定義さ れるメンバ関数

仮想関数 ex20_virtual.cc // 派生クラス1 class deriv1 : public base { public: #include <iostream> using namespace std; class base { // 基本クラス public: int i; base(int x) { // コンストラクタ i = x; } virtual void func() { // 仮想関数 cout << "baseのfunc()を使う: "; cout << i << endl; }; // 派生クラス1 class deriv1 : public base { public: deriv1(int x) : base(x) {} // コンス トラクタ:基本クラスのコンストラク タで初期化 void func() { cout << "deriv1のfunc()を使う: "; cout << i*i << endl; } };

仮想関数 ex20_virtual.cc 続き // 派生クラス2 class deriv2 : public base { public: deriv2(int x) : base(x) {} // コンストラクタ:基本ク ラスのコンストラクタで初期化 void func() { cout << "deriv2のfunc()を使う: "; cout << i+i << endl; } };

仮想関数 ex20_virtual.cc 続き 同じ関数を3回呼び出している (ように見える) int main() { base *p; // クラスbase型のポインタ base b(10); // クラスbaseのオブジェクト deriv1 d1(10); // クラスderiv1のオブジェクト deriv2 d2(10); // クラスderiv2のオブジェクト p = &b; // ポインタはクラスbaseのオブジェクトを指す p->func(); // baseのfunc()を使用する p = &d1; // ポインタはクラスderiv1のオブジェクトを指す p->func(); // deriv1のfunc()を使用する p = &d2; // ポインタはクラスderiv2のオブジェクトを指す p->func(); // deriv2のfunc()を使用する return 0; } 同じ関数を3回呼び出している (ように見える)

実行例 試しに12行目のvirtualを除いてみたらこうなる p->func();を3回実行したが、結果は違う $ ./a.exe baseのfunc()を使う: 10 deriv1のfunc()を使う: 100 deriv2のfunc()を使う: 20 $ ./a.exe baseのfunc()を使う: 10

仮想関数 仮想関数は継承したクラスで上書きできる クラスbase 上書き クラスderiv1 クラスderiv2 virtual void func() { // 仮想関数 cout << "baseのfunc()を使う: "; cout << i << endl; } 上書き クラスderiv1 void func() { cout << "deriv1のfunc()を使う: "; cout << i*i << endl; } クラスderiv2 void func() { cout << "deriv2のfunc()を使う: "; cout << i+i << endl; }

仮想関数 関数のオーバーロードとの違い 関数のオーバーロードでは、引数の型が違う必要がある 仮想関数では、引数の型は同じ

純粋仮想関数

純粋仮想関数 具体的な関数の中身を定義せずに、引数と戻り値の みが定義された仮想関数 関数の中身は派生クラスで定義する必要がある 書式 抽象クラス 少なくとも1つの純粋仮想関数を含むクラス 不完全なクラスであり、オブジェクトを作成できない virtual type func-name( parameter-list) = 0;

純粋仮想関数 ex21_pure_virtual.cc #include <iostream> using namespace std; class keisan { // 基本クラス public: int i; keisan(int x) { // コンストラクタ i = x; } virtual void func(int x) = 0; // 純 粋仮想関数 }; class tasu : public keisan { // 派生 クラス1(足し算) public: tasu(int x) : keisan(x) {} // コンス トラクタが呼ばれれば、基本クラスの コンストラクタで初期化 void func(int x) { cout << i + x << endl; } };

純粋仮想関数 ex21_pure_virtual.cc class kakeru : public keisan { // 派生クラス2(かけ算) public: kakeru(int x) : keisan(x) {} // コンストラクタが呼ばれれば、基 本クラスのコンストラクタで初期 化 void func(int x) { cout << i * x << endl; } }; int main() { // keisan b(10); // クラスkeisanのオブ ジェクト(エラー) tasu t(10); // クラスtasuのオブジェクト kakeru k(10); // クラスkakeruのオブジェ クト keisan *p; // クラスkeisan型のポインタ p = &t; // ポインタはクラスtasuのオブジェ クトを指す p->func(5); // tasuのfunc()を使用する p = &k; // ポインタはクラスkakeruのオブ ジェクトを指す p->func(5); // kakeruのfunc()を使用する return 0; }

演習課題

第13回演習課題(1) 1. 任意の数nをキーボードから入力して、その数nの 階乗n!の桁数を求めるプログラムを作成せよ。そし て、横軸:n、縦軸:n!の桁数のグラフを書け(nは1 から100とする)。ただし、桁数は近似で良い。

第13回演習課題(2) 2. プログラムを作り、次の問いを解け 左右どちらから読んでも同じ値になる数を回文数という 2桁の数の積で表される回文数のうち、最大のものは 9009 = 91 × 99 である では、3桁の数の積で表される回文数の最大値を求めよ

提出に関して 提出するもの ソースファイル(.ccまたは.cpp ファイル) ファイル名はkadai0108_学籍番号_課題番号.cc(.cpp) (Visual Studioの場合) ファイル名はkadai0108_学籍番号_課題番号_v.cc (.cpp) 実行結果の出力と講義に関するコメント .txt ファイルで、学籍番号、氏名を含む ファイル名はreport0108_学籍番号.txt とする

提出に関して(続き) 提出期限 提出方法 注意点 1月22日(水) 00:00 授業支援システムから提出 1月22日(水) 00:00 提出方法 授業支援システムから提出 注意点 ファイル名の命名規則が間違っているものは採点しない コンパイルの通らないものは採点しない