オブジェクト指向言語 オブジェクト指向言語演習 第23回 C++言語 クラスの詳細 スケジュール(C++言語) 20. 21. 22. 23. 24. オブジェクト指向技術 C++言語 コンソール入出力とクラス C++言語 クラスの継承 C++言語 クラスの詳細 C++言語 オーバーロード (2004/12/13) (2004/12/20) (2004/12/20) (2005/01/17) (2005/01/17) -- 希望者に対するC++補講-- (予定日未定) 25. C++言語 26. C++言語 27. C++言語 クラスの継承 マニピュレータ, ファイル入出力 テンプレート (2005/01/24) (2005/01/24) (2005/01/31) 期末試験 2005/02/01 (9:00-10:30 (他の時間が空けば移動)) (授業期間終了は1月31日ですが、2月1日は補講日です) 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 2 C++言語 クラスの詳細 C++ Language Detail description for Class 前回までの復習(1) C++のコンソール入出力 入力演算子 >> cin >>「 変数」; 出力演算子 << 「変数、式」 << cout; クラスの概要 クラスの宣言 アクセス制限 private, public, protected クラスの定義 クラスで宣言されたメンバ関数の内容を定義する オブジェクトの宣言 クラスは「型」であるので、実際に使うときには「変数」 に相当するオブジェクトを宣言し、使用する コンストラクタとデストラクタ オブジェクトが生成・消滅されたときに実行される 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 4 前回までの復習(2) クラスの継承 あるクラスが他のクラスの性質をそのまま受け継ぐ仕組み B 継承されるクラス スーパークラス(B) class B { } 継承したクラス サブクラス(D) class D: public B{ }; インライン関数 D 関数を展開する inline int func {} 戻り値型intの関数func 自動インライン関数 クラス宣言内のメンバ宣言時に関数を定義する インライン関数の制限 静的変数、繰り返し制御、switch文や再帰を用いた場合 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 5 オブジェクトの代入(1) 2つのオブジェクトの型が同じ(オブジェクトを生成 した元のクラスが同じ)であれば、オブジェクトの代 入を行うことができる。 代入は元のオブジェクトの内容を代入先のオブジェ クトに全てコピーする 例え配列のように大きな領域を使用するものをメンバとし て持っていたとしても(文字列の代入ができる) ただし、同じ内容をもつオブジェクトでも元のクラ スが異なる場合には代入は出来ない。 この場合は内容を一つ一つコピーする必要がある 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 6 オブジェクトの代入(2) ●リスト3.1 (オブジェクト代入の例) #include <iostream> using namespace std; // class myclass { // int a, b; // public: void set(int i, int j) { a void show() { cout << a << }; int main() { myclass o1, o2; std名前空間を省略して使用する クラスmyclassの宣言 private属性の変数a,bを宣言 = i; b = j; } ' ' << b << "\n"; } // メンバ関数set // メンバ関数show // どちらもinline関数 // オブジェクトo1とo2を宣言する o1.set(10, 4); // メンバ関数setでprivate属性のa,bの値を設定する o2 = o1; o1.show(); o2.show(); return 0; // o1をo2に代入する // メンバ関数showを使用 } 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 7 関数へのオブジェクトの引き渡し 関数に引数として変数などのデータを渡すのと同じ 方法でオブジェクトを引数として渡すこともできる 関数へはデフォルトとして「値呼び出し(pass by value)」が使われる 値呼び出しなので、引数で渡されるオブジェクトの コピーが生成されて関数に渡される 従って、関数内でオブジェクトを変更しても呼び出し元の オブジェクトに変更は反映されない。 関数が呼び出されたときにコピーされ、終了時には破棄さ れる。コンストラクタ・デストラクタは呼び出されない。 C言語と同様に、関数側での変更を受け取りたい場合 にはポインタを渡す。 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 8 関数からのオブジェクトの返し 関数にオブジェクトを渡すことができるのと同様に、 関数からオブジェクトを返すことができる。 関数からオブジェクトを戻すときにはreturn文を使 用する。 変数を返す関数(これまでC言語で学習した)と同じ ように、返す値の型(クラス)で関数を宣言する class samp { char s[80]; public: void show() { cout << s << "\n"; } void set(char *str) { strcpy(s, str); } }; samp input() { char s[80]; samp str; cout << "文字列の入力: "; cin >> s; str.set(s); return str; } samp型のオブジェクトを返す関数input 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 9 フレンド関数の概要(1) フレンド関数(Friend Function) 関数をあるクラスのメンバにすることなく、関数からその クラスの非公開(private)メンバにアクセス対場合に使用す る フレンド関数の用途 演算子のオーバーロード ある種の入出力関数 1つの関数から2つ以上の別々のクラスの非公開メンバへア クセス フレンド関数の宣言 アクセスを許可するクラスのpublicエリアに宣言をする friend 関数の型 関数名; 例 friend int isfactor(myclass ob); 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 10 フレンド関数の概要(2) フレンド関数の例 #include <iostream> using namespace std; class myclass { int n, d; public: myclass(int i,int j){ n = i; d = j; } // myclassのフレンドを宣言する friend int isfactor(myclass ob); }; int main() { myclass ob1(10, 2), ob2(13, 3); if(isfactor(ob1)) cout << "2は10の因数\n"; else cout << "2は10の因数ではない\n"; if(isfactor(ob2)) cout << "3は13の因数\n"; else cout << "3は13の因数ではない\n"; return 0; int isfactor(myclass ob) { if(!(ob.n % ob.d)) return 1; else return 0; } // isfactor()関数は、dがnの因数で // あれば真を返す } isfactorはmyclassのメンバ関数ではな いので、ob1.isfactor; とは書かない frined関数からprivate属性にアクセスするためには、そのオ ブジェクトを指定しなければならない (例 ob.n) 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 11 フレンド関数の概要(3) #include <iostream> using namespace std; class truck; //前方宣言(宣言前に使うため) class car { int passengers; int speed; public: car(int p, int s) { passengers = p; speed = s; } friend int sp_greater(car c, truck t); }; class truck { int weight; int speed; public: truck(int w, int s) { weight = w, speed = s; } friend int sp_greater(car c, truck t); }; int sp_greater(car c, truck t) {return c.speed - t.speed;} int main(){ int t; car c1(6, 55), c2(2, 120); truck t1(10000,55), t2(20000,72); cout << "c1とt1を比較:\n"; t = sp_greater(c1, t1); if(t<0) cout << "トラックが速い\n"; else if(t==0) cout << "速度は同じ\n"; else cout << "Car is faster.\n"; cout << "\nc2とt2を比較:\n"; t = sp_greater(c2, t2); if(t<0) cout << "トラックが速い\n"; else if(t==0) cout << "速度は同じ\n"; else cout << "乗用車が速い\n"; return 0; } sp_greater関数 carの速度がtruckよりも速い場合は正の値、同じであれば0、遅い場合は負を返す 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 12 オブジェクトの配列(1) オブジェクトは変数であり、ほかの方の偏すと同じ 機能と属性を持っている したがって、変数と同じように配列の宣言が可能で ある #include <iostream> using namespace std; int main() { samp ob[4]; int i; class samp { //sampクラスの宣言 int a; public: void set_a(int n) { a = n; } int get_a() { return a; } }; // 配列宣言 for(i=0; i<4; i++) ob[i].set_a(i); for(i=0; i<4; i++) cout << ob[i].get_a( ); cout << "\n"; return 0; } 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 13 オブジェクトの配列(2) コンストラクタを利用して初期化する #include <iostream> using namespace std; class samp{ //sampクラスの宣言 int a; public: void samp(int n) int get_a() { return a; } }; samp::samp(int n){ a = n; } //引数1つのコンストラクタ関数 int main() { samp ob[4]={-1,-2,-3,-4}; // コンストラクタによる初期化 int i; for(i=0; i<4; i++) ob[i].set_a(i); for(i=0; i<4; i++) cout << ob[i].get_a( ); cout << "\n"; return 0; } 初期化時にコンストラクタを呼び出す samp ob[4]={samp(-1), samp(-2), samp(-3), samp(-4)}; 1つの引数しかとらないコンストラクタの場合は簡略 化することができる 13.Dec.2004 samp ob[4]={-1,-2,-3,14}; Object Oriented Language - Y.Nagasaka: [email protected] 14 オブジェクトのポインタ ポインタを利用してオブジェクトにアクセスが可能 通常の「 . 」演算子の代わりに「->」演算子が使わ れる #include <iostream> using namespace std; class samp { int a, b; public: samp(int n, int m) {a = n; b = m;} //コンストラクタ int get_a() { return a; } int get_b() { return b; } }; 13.Dec.2004 int main() { samp ob[4] = { samp(1, 2), samp(3, 4), samp(5, 6), samp(7, 8) }; int i; samp *p; p = ob; // 配列の開始アドレスを取得する for(i=0; i<4; i++) { cout << p->get_a() << ' '; cout << p->get_b() << "\n"; p++; // 次のオブジェクトに進む } cout << "\n"; return 0; } Object Oriented Language - Y.Nagasaka: [email protected] 15 thisポインタ 呼び出しを行ったオブジェクトを参照するthisとい う特別なポインタがある #include <iostream> #include <cstring> using namespace std; class inventory { char item[20]; double cost; int on_hand; public: inventory(char *i, double c, int o){ strcpy(this->item, i); this->cost = c; this->on_hand = o; } void show(); }; 13.Dec.2004 void inventory::show() { cout << this->item; cout << ": $" << this->cost; cout << " 在庫: " << this->on_hand << "\n"; } int main(){ inventory ob("レンチ", 4.95, 4); ob.show(); return 0; } Object Oriented Language - Y.Nagasaka: [email protected] 16 newとdelete C言語ではメモリを動的に割り当てるためには malloc関数を開放するためにはfree関数を使用する。 C++ではnewとdeleteをしようする。 例: typeクラスの領域を確保しポインタをp-varに割り当てる p-var = new type; p-varの解法 delete p-var; typeクラスの領域を確保しポインタをp-varに割り当てる。 その際に、初期値を与える p-var = new type(initial value); 配列を割り当て、その先頭ポインタを渡す p-var = new type[size]; 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 17 newとdelete // 動的変数を初期化する例 #include <iostream> using namespace std; int main() { int *p; p = new int(9); // 初期値として9を格納する if(!p) { cout << "メモリ割り当てエラー\n"; return 1; } cout << "pが指している整数型は: " << *p << "\n"; delete p; // メモリを解放する return 0; } 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 18 課題1 教科書p.82の「前章の理解度チェック」をテ キストファイルで作成し、提出しなさい。 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 19 課題2 課題1を拡張して、円の面積を返すメンバ関数を追加 したプログラムを作成しなさい(oo21-2.cc)。 Circle int main() { int r; double area; Circle circle1; circle1.setR(7); r = circle1.getR(); cout << “circle1: r=“ << r << “\n”; cout << “The area is” <<circle1.getArea() << “\n”; -r: int +setR(rr: int): void +getR(): int +getArea(): double } 13.Dec.2004 Object Oriented Language - Y.Nagasaka: [email protected] 20 コンパイルと実行 まずはじめに 一度実行すればよい 作業ディレクトリの作成 $ mkdir ~/wrk/ $ mkdir ~/wrk/oo/ 次に 作業ディレクトリへの移動 プログラミング コンパイル・リンク 実行 $ cd ~/wrk/oo $ vi oo20-1.cc $ g++ -o oo20-1 oo20-1.cc $ ./oo20-1 * C++言語プログラムのファイル名は、.cc でなければならない 注 意 13.Dec.2004 * プログラムが終了しなくなったら Ctrl キーを押しながら c を押して強制終了すること Object Oriented Language - Y.Nagasaka: [email protected] 21
© Copyright 2024 ExpyDoc