プログラミング言語論

24
ププププププププププ プププププ ププ プ 12 プ ププププププププ

Upload: zarola

Post on 06-Jan-2016

1.030 views

Category:

Documents


4 download

DESCRIPTION

プログラミング言語論. 第 12 回 オブジェクト指向. 情報工学科 篠埜 功. プログラムの分割. 大きなプログラムは、分割して開発するのがよい。 手続きは分割の最も基本的なものである。. Module( モジュール ) は、関連する変数、手続き、型を一つにまとめるものである。 手続きが処理するデータの型を一つのモジュール内に入れ、データ型の実装を隠す。. (参考) Opaque type. Modula-2 では、モジュールから型を export するとき、 type stack; のように、型名だけを export することができる。 - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: プログラミング言語論

プログラミング言語論

情報工学科 篠埜 功

第 12 回 オブジェクト指向

Page 2: プログラミング言語論

プログラムの分割

大きなプログラムは、分割して開発するのがよい。手続きは分割の最も基本的なものである。

Module( モジュール ) は、関連する変数、手続き、型を一つにまとめるものである。

手続きが処理するデータの型を一つのモジュール内に入れ、データ型の実装を隠す。

Page 3: プログラミング言語論

(参考) Opaque typeModula-2 では、モジュールから型を export するとき、 type stack;のように、型名だけを export することができる。これを opaque export といい、 export された型をopaque type という。Import した側では、 stack 型の変数を var s, t: stackのように宣言できる。Modula-2 は opaque 型について、代入、等しさのチェックをサポートする。ただし、 opaque 型はポインタに限られ、等しさの判定はポインタの等しさで判定される。

Page 4: プログラミング言語論

C++ におけるクラスC++ におけるクラスは、レコード (C では構造体と呼ばれる ) を一般化したもの。クラスを宣言した後はクラス名を型名として使用でき、その型の変数を宣言したり、オブジェクトを生成したりできる。

struct Stack { int top; char elements [101]; char pop(); void push (char); Stack(); };

(例) class Stack { public: int top; char elements [101]; char pop(); void push (char); Stack();};

(参考) Simula 67 のクラスを C に移植して設計されたのが C++ 。

Page 5: プログラミング言語論

C++ でのクラス宣言 struct X { <declarations> };は、 class X { public : <declarations> }と同じであり、 class X { <declarations> };は、 struct X { private : <declarations> };と同じである。

Page 6: プログラミング言語論

クラス宣言の例 class Stack { int top; int size; char *elements; public: Stack (int n) {size=n; elements = new char[size]; top=0;} ~Stack() { delete elements; } void push (char a) {top++; elements[top] = a; char pop() {top--; return elements[top+1];};

Page 7: プログラミング言語論

オブジェクトの生成、破棄C++ ではオブジェクトは new で生成し、 delete で破棄する。任意の型 T について、 new Tによって T 型のオブジェクトが生成され、それへのポインタが返される。 delete pによって、 p が指しているオブジェクトが破棄される。( 例 ) 前ページの例の、 elements = new char [size]によって、 char 型を要素とする長さ size の配列が生成される。 elements[0], elements[1], …, elements[size-1] によって配列の各要素が得られる。また、 delete elements によって配列オブジェクトが破棄される。

Page 8: プログラミング言語論

例 : 後ろからも要素を追加可能なリスト

class List { Cell * rear; public: void put (int); void push (int); int pop(); int empty() { return rear == rear->next; } List() { rear = new Cell (0); } ~List() { while(!empty()) pop(); } };

class Cell { int info; Cell * next; Cell (int i) { info = i; next = this; } Cell (int i, Cell *n) {info = i; next = n; } friend class List; };List 中の関数は Cell の privateなメンバーにアクセスできる。

Page 9: プログラミング言語論

例(続き)

void List::push (int x) { rear->next = new Cell (x, rear->next); } void List::put (int x) { rear->info = x; rear = rear->next = new Cell (0, rear->next); } int List::pop() { if (empty()) return 0; Cell * front = rear->next; rear->next = front->next; int x = front->info; delete front; return x;}

Page 10: プログラミング言語論

テンプレート(例) template <class T> class Stack { int top; int size; T * elements; public: Stack (int n) {size=n; elements = new T[size]; top=0;} ~Stack() { delete elements; } void push (T a) { top++; elements[top]=a; } T pop() { top--; return elements[top+1]; } };

Stack 型の変数を宣言したりオブジェクトを生成したりするとき、 Stack<int> s(99); のように型を <> 内に引数として与える。

Page 11: プログラミング言語論

C と C++C++ は 1983 年、 Bjarne Stroustrup によって設計、開発された。 C の拡張として設計されており、ほとんどの C 言語のプログラムは C++ のプログラムであり、意味も同じである。ただし、 C と C++ で意味が違うプログラムがある。

コメントは、 C では /* … */ だが、 C++ では // …(C99 では // もコメントとして使えるが )

(例) int f (int a, int b) { return a //* */ b ;}

return の右に書かれている式は、 C89では a/b, C++ およびC99 では a となる。

Page 12: プログラミング言語論

C と C++ (続き)

int x[99]; void f() { struct x {int a;}; sizeof (x); }

C++ では、構造体型を名前付きで宣言する構文で宣言した場合、その名前のみで構造体型を表せる。(例1) struct test {int a;} test x;のように書いてよい。 C では、 struct test x; と書く必要がある。 (C++ で struct test x; と書いてもよいが。 )

(例 2 ) sizeof(x) は、 C では配列x のサイズ、 C++ では構造体 x のサイズ。 C では、構造体 x のサイズはsizeof(struct x)と書かなければならない。

Page 13: プログラミング言語論

C と C++ (続き)C では、 sizeof(‘a’) は sizeof(int) と同じである。C++ では、 sizeof(‘a’) は sizeof(char) と同じである。

C では、列挙型のサイズは sizeof(int) である。C++ では、列挙型のサイズは、処理系依存である。

(列挙型の例) enum color {RED, BLUE, YELLOW};のように列挙型 color を宣言すると、 C ではsizeof(enum color) は sizeof(int) と同じ、 C++ では処理系依存。

Page 14: プログラミング言語論

オブジェクト指向オブジェクト指向はシミュレーションを記述することを意図して考え出された。シミュレーションの中の要素がオブジェクトである。

(例) Simula ( Simulation language, 1967 )• Ole-Johan Dahl, Kristen Nygaard が開発• 最初のオブジェクト指向言語 ( オブジェク

ト指向という言葉はまだなかったが、オブジェクト指向における種々の概念が含まれていた )

• ALGOL の拡張として設計された• 空港のシステムの記述が重要な例となっ

ていた

Page 15: プログラミング言語論

オブジェクト指向[ オブジェクトの例 ] 乗客、航空会社のカウンター、行列、チケット、…

(外側からの見た場合)オブジェクト間でメッセージをやりとりすることにより計算が進んでいく。

(内側から見た場合)メッセージを受け取ったら、それに対応する手続きを実行する。この手続きのことを、メソッド (method) あるいはメンバ関数 (member function) という。

Page 16: プログラミング言語論

クラスの階層構造Shape

Box Ellipse

Circle

Line Text

Box Ellipse Line TextCircle

Shape

Page 17: プログラミング言語論

継承 (inheritance)

• 子クラスは親クラスのメソッド、変数を継承する(親クラスのメソッド、変数が子クラスのメソッド、変数になる)。

• 子クラスでは、追加でメソッドや変数を定義できる。同じ名前の場合には上書き (override) される。

(注意) overload は override とは全く別の概念。Overload は、引数の数や型が違うメソッドに同じ名前をつけること。

Page 18: プログラミング言語論

C++ の例C++ では、継承は以下のように記述する。

class Box : public Shape { … }

すべてのメンバーをvisibility を保って継承する。

C++ では親クラスを基底クラス (base class) 、子クラスを派生クラス (derived class) という。

class Box : private Shape { … }

継承されたメンバーは default で privateメンバーになる。

Page 19: プログラミング言語論

仮想関数 (virtual function)

class B { public: virtual char f () { return ‘B’; } char g() { return ‘B’; } char testF() {return f(); } char testG() { return g(); } };

class D : public B { public: char f () { return ‘D’; } char g() { return ‘D’; } }; #include <iostream> int main (void) { D d; std::cout << d.testF() << d.testG() << "\n"; return 0; }

d.testF() は’ D’ を返し、d.testG() は’ B’ を返す。

メソッド宣言に virtual というキーワードをつけると、(コンパイル時でなく)実行時にメソッドが選択される。

Page 20: プログラミング言語論

補足メソッドは、( C++ コンパイラ内で)引数を1つ追加した関数へコンパイルすればよい。

char testF() { return f(); }

char testF (B * this) { return this->f(); }

d.testF() を testF(d) にコンパイルすれば、(クラス B において f は virtual なので) testF の本体で d に対してメッセージ fが送られることになり、’ D’ が返される。

Page 21: プログラミング言語論

C++ の特徴• C との backward compatibility をできる限り保ちつつオブジェクト指向をサポートするように設計された。

• オブジェクトを C の構造体の拡張とした。つまり、オブジェクトは関数の activation recordや local block 内に allocate され得る。(もちろんヒープにも allocate できるが。)

• オブジェクト指向ではないプログラミング(命令型のプログラミング)もできる。(プログラミングのスタイルをプログラマに強要しない。)

• Multiple inheritance をサポートする。(授業範囲外とする)

Page 22: プログラミング言語論

オブジェクト指向言語のまとめ

• Dynamic lookup (メッセージを受け取ったときに実行されるメソッドは実行時に決まる)

• Abstraction ( public 関数がインターフェースとなり、データや実装は他の部分から見えない)

• Subtyping (派生クラス型の式は基底クラス型の式と置き換えてもよい( public で継承している場合))

• Inheritance (継承。コード量が削減され、コードを修正しやすくなる。)

オブジェクト指向言語 (object-oriented language)は、オブジェクトを持ち、以下の4つの特徴を持つ。

Page 23: プログラミング言語論

注意Subtyping と inheritance は異なる概念である。(例)Queue --- first-in, first-outStack --- last-in, first-outDequeue --- 両端から出し入れ可能な queue

Dequeue の派生クラスとして Queue クラスとStack クラスを実装することができる (private な継承を使って必要なメソッドのみ public にすれば ) 。しかし、 Queue, Stack は Dequeue の subtype ではない。

Page 24: プログラミング言語論

(参考) Data invariant• 制御がオブジェクト内にないときに常に成り立

つ性質• (例) bounded buffer (長さ制限付き queue )– put(x), get() の2つのメソッドからなる。– 配列に要素を格納し、 front と rear で範囲を示す。

配列の最後の要素の次は最初の要素とする。

オブジェクトは、 data invariant を考慮しつつ設計する

バッファーは front と rear が等しいとき空 Rear の次の要素が front のときバッファーは一杯 Front と rear の間に、入力された順に要素が並んで

いる。