授業中に作成したプログラムを片っ端から乗っけていきです。C++ を中心に掲載中。

classによって、オブジェクトを構成単位としてソフトウェアを構築する、オブジェクト指向プログラミングが可能になる。

10.1 クラスとオブジェクトの概念

クラス
ユーザが新たな型を定義する道具。クラスの定義に従ってオブジェクトは作成される。作成されたオブジェクトをインスタンス(実体)と呼ぶ。構造体、共用体と同じ構文。
  • メンバ関数:各クラスに対して定義される関数。メソッドともいう。
  • メンバ変数:基本的にインスタンス単位に生成される変数。
オブジェクト
機械的にひとつにまとまったもの。実世界の「もの」や役割などの「こと」を抽象化したもの。
オブジェクト指向とは、複雑な現実世界を「オブジェクトとそれらの相互関係(メッセージによる協調動作)」で記述しようとする考え方。

クラスはメモリを占有しないが、オブジェクトはメモリを占有する。
ブラックボックス化―古典的な例は車の運転
車の「振舞い」(ハンドルを回すとどうなるか、アクセルを踏むとどうなるか、ブレーキを踏むとどうなるか}はすべてに共通。車を使う際に、やりたいと思うことが車の内部でどのように引き起こされたかについては知る必要はない。
効用は二つ
  • システム開発が簡単になる。設計者は問題を部分部分に分けて設計していけばよい。
  • 抽象したもの(本質)を実現している部分を変更しても、その本質は何の影響も受けない。
(1)カプセル化 Encapsulation(情報の隠蔽 Infomation Hiding)
オブジェクト(メンバ変数、メンバ関数)に関する処理を外部から切り離してまとめて記述。カプセルに含まれた内部(プログラム、データ)は、外部から隠蔽(保護)される。
  • インターフェース オブジェクトに対する処理のための手続き。オブジェクトに対する処理は、オブジェクトで定義されたインターフェースを通してのみ実現。外部から参照できるものの、内部のみで用いるものがある。
  • オブジェクトの内部の実装に関して設計者は全責任を負う。
(2)継承 Inheritance
似たような属性を持ったほかのクラスの定義を流用して、差分だけを改めて定義する。派生クラスは基本クラスのメンバを継承し、より具体的なクラスを作成する。独自意の実装に変更できる。
(3)多層性 Polymorphism
ひとつのオブジェクトが複数の型を持つ。スーパクラスへの操作としてプログラムを記述できるので、サブクラスの細かい修正や追加などに対して強い(保守性が高い)プログラムになる。

10.2 クラス定義のパターン

[プログラムサンプル挿入予定]
AAA::BBB メンバBBBはクラスAAAのスコープ内にある。::スコープ解決演算子。
クラスのメンバはデフォルトでは非公開(private)メンバになる。
クラスの外から参照する必要のあるメンバ変数やメンバ関数は後悔(public)セクションの中におく必要がある。

10.3 作成手順

1)クラスの定義
(1)クラスの宣言
  • class クラス名 {・・・};
  • アクセス制限の指定、メンバ変数の定義、メンバ関数の宣言
(2)コンストラクタの定義
  • 型名 クラス名::同じクラス名(型 引数)
  • インスタンスの初期化を行う。デフォルトによる定義から明示的な定義まで、さまざまな記述法がある。
(3)メンバ関数の定義
  • 内部定義(インライン定義)クラス宣言外で関数定義。プロトタイプ宣言なし。
    • 戻り値の型名 メンバ関数名(型){・・・}
    • private メンバにアクセスするには、public メンバ関数を呼び出してアクセスすること。頻繁にメンバ関数を呼び出す場合、呼び出し速度を上げるために、インライン関数に定義するとよい。→9.7を参照。
  • 外部定義 クラス宣言外で定義。どのクラスのメンバかを明治するために、スコープ解釈演算子が必要。
    • 型名 クラス名::メンバ関数 (型 引数){・・・}
2)クラスの利用
(1)オブジェクトの作成(インスタンス)
    • クラス名 オブジェクトの変数名;
  • クラスのインスタンス Sample sobj;
  • オブジェクトsobjはSampleというユーザ定義の型を持つ変数と宣言。
  • クラスのインスタンスへのポインタSample* sptr;
(2)メンバ関数の呼び出し
  • インスタンスを指定し、これに対して関数を呼び出す方法は二つ。構造体のメンバ呼び出しと同様。
    • メンバ選択演算子. sobj.fumc1();
    • アロー演算子-> sqtr-> fumc2();
  • メンバ関数内でメンバ変数を使用する場合は、変数のみでよい。a
  • クラス内で自身のメンバ関数を呼び出す場合は、関数名のみでよい。
親クラスの関数を呼び出す場合
  • 親クラスのメンバ関数は現在のインスタンスに含まれているから、
例:
MetaSample--Sampleの場合
MetaSample::Func()として呼び出す。
単にFunc()とした場合、自分のクラス内にFunc()があればそれ、なければ親クラスのFunc()が呼び出される。

10.4 コンストラクタ/デストラクタ

インスタンスの初期化/領域開放のための(特殊メンバ)関数。
例:
Sample::Samplw(){・・・}
Sample* a;
a=new Sample(); //Sampleなクラスのメモリ領域を確保し、コンストラクタが呼び出される。
deleta a;//Sampleクラスのデストラクタを呼び出し、領域を開放する。
1)コンストラクタ
インスタンスを作成したときに、すぐに初期化しておきたい。自動的に呼び出され初期化する。クラス名と同名。
戻り値は指定しないが、暗黙にそのクラス自身へのポインタが返される。voidも指定できない。
(1)初期化リスト
オブジェクトのメンバ変数を初期化するための特殊な初期化りすと記述方。
クラス名():メンバ変数名(初期値),・・・;
参考 これを初期化構造分と呼ぶ。 変数nを1に初期化するためには:n(1); これは、int n=1;と等価。
(2)ディフォルトコンストラクタ
引数を一つも持たない、またすべてのひきすうがオプショナルのコンストラクタ。
コンストラクタをひとつも定義しない場合、コンパイラが何の処理もしない空のディフォルトコンストラクタをひとつ用意する。
例:Sample();
(3)初期値設定
コンストラクタの定義の中で初期化
オブジェクト名 = 初期値;

2)ディストラクタ

インストラクタが消滅するときには、現実もなくなって欲しい。コンストラクタが確保したメモリ領域を開放する。名前は“~クラス名”。引数も戻り値もない。
例: Sample::~Sample(){・・・}

10.5 継承

(1)単一継承
ひとつの基本クラスのみを持つ派生関係。
class 派生クラス名:[アクセス]基本クラス名{・・・}
Sample-Aクラス(基本クラス)を継承してSample-Cクラス(派生クラス)を定義する。
class Sample-A{
public:int a;
}
class Sample-C:public Sample-A{
public:int c;
}
main{・・・}
Sample-AクラスのpublicメンバをSample-Cクラスでアクセス制御の対象とする。
(2)多重継承
複数の基本クラスから一つの派生クラスを継承する。
Sample-A,Sample-Bクラス(共に基本クラス)を継承してSample-Cクラス(派生クラス)を定義する。
class Sample-A{
public: int a;
}
class Sample-B{
public: int b;
}
class Sample-C:public Sample-A, public Sample-B{
public: int c;
}
main(){・・・}
Sample-A,Sample-BクラスのpublicメンバをSample-Cクラスでアクセス制御の対象とする。

10.6 アクセス管理

アクセス指定子として、private、protected、publicを指定。
private
クラス外からはアクセス不可
public
クラス外からもアクセス可能
protected
派生クラスから基本クラスのメンバへのアクセスのみを許可
class Sample{
private cariables //defaultはprivate
protected:
protecetd variables
int func1(){}
public:
public variables
int func2(){}
private:
private cariables
int func3(){}
};

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Creative Commons

Creative Commons License
この作品は、クリエイティブ・コモンズ・ライセンスの下でライセンスされています。

メンバーのみ編集できます