C++ミニツアーに関する世界観です。C++も参照のこと。
クラスは、C++の主要な機能で、ユーザーが独自に作ることのできるデータ型を宣言できる。
クラスでは、データ型を含む構造体と、その構造体を操作するメソッドをひとつにまとめることができる。
C言語では、構造体を操作する関数は作ることができるが、その構造体を間違った方法でアクセスする関数から、構造体のデータを守る術がない。
C++では、データ型の構造体とその構造体を操作するメソッドをまとめた上で、アクセス指定子を宣言することで、限られた範囲のメソッドからのみデータ構造を操作することができる。このような考え方をカプセル化と呼ぶ。
アクセス指定子には、public(公開)、private(非公開)、protected(派生クラスのみに公開)がある。これ以外にも、関連するキーワードとしてfriendとvirtualがある。friendを使うことで、一部のクラスや関数にだけ特別にデータにアクセスすることができるようにすることができる。これをfriendクラス、friend関数と呼ぶ。
C++で自分で作ったクラスは、構造体のように静的に宣言して、ローカルスコープで使う場合は、通常の型と同じように宣言し、メソッドはobj.meth()のように呼び出す。malloc()やfree()のように動的にメモリに確保する場合は、new/delete演算子を使って、型宣言に*をつけ、ClassA *obj = new ClassA();とする。この時、メソッドの実行はアロー演算子を用いてobj->meth()のように呼び出す。
クラスと同名のメソッドはコンストラクタと呼ばれ、クラスが最初に作られた時に初期化に必要な処理を行うメソッドとして実行される。クラスと同名に~をつけたメソッドはデストラクタと呼ばれ、クラスが破棄された時に後処理を行うメソッドとして実行される。
class Hoge { private: int v; public: Hoge(int x) { v = x; } void hogeAssign(int x) { v = x; printf("%d\n", v); } void hogeIncr() { v++; printf("%d\n", v); } int hogeGet() { return v; } }; void main(){ Hoge *obj = new Hoge(10); obj->hogeIncr(); obj->hogeAssign(100); obj->hogeIncr(); obj->hogeIncr(); delete obj; }
クラス内の変数はメンバ変数あるいはフィールド変数、関数はメンバ関数あるいはメソッドと呼ばれる。クラスを元に作られた「生成された変数」はインスタンス変数と呼ばれる。
クラスは、継承を行うことで、既存のクラスに対して新しいデータ型やメソッドを追加し、publicやprotectedな変数を操作したり、さまざまな機能を追加することができる。
継承は以下のように行う。
class ExHoge : public Hoge { public: void hogeIncr10() { for (int i = 0; i < 10; i++) { hogeIncr(); } } };
クラスを継承した際、同名のメソッドを定義することで、元のクラスのメソッドを「上書き」し、書き換えることができる。これをオーバーライドと呼ぶ。オーバーライドを使うことで、クラスの一部分だけを独自に自分で実装し、処理内容を書き換えることができる。
また、C++ではオーバーロードを使うことで、同じ名前のメソッドを別の引数の型で使い分けたり、場合によって別のメソッドが実行されるようにできる。
C++では演算子をオーバーロードすることで、+や=、[]や()などの演算子もオーバーロードできる。
int Hoge::operator+(Hoge &h) { return v + h.hogeGet(); }
C++ではiostereamで演算子<<と>>を用いて入出力を行うが、これは演算子をオーバーロードして実現されている。
また、virtualキーワードを使うことで、継承したメソッドを仮想関数にできる。仮想関数を用いると、たとえばClassAのメソッドを実行するのか、それともClassAを継承したClassBの同名のメソッドを実行するのかを「動的にバインディング」できる。仮想関数を使うには、基本クラスのメソッドにvirtual宣言をつけた上で、派生クラスでそれをオーバーライドする。このような考え方をポリモーフィズムと言う。
例外は、エラー処理の専用の制御フローで、どこかの時点でエラーができた時に、「例外を投げ」、それを「キャッチ」することで、エラー処理を分かりやすく単純にできる。
テンプレートは、さまざまな型を汎用的に使うことができるように、型の中の型を引数として受け渡すことができる。
template <typename T> T funcHoge (T x, T y) { return x + y; }
インライン関数は、特定の関数を呼び出しではなくマクロのように、命令コード中に埋め込み展開することができる。
参照渡しは、ポインタのように変数を参照型として扱える機能。Cにはポインタがあるだけで参照渡しをすることができなかった。C++では参照渡しの機能を標準の仕様として使うことができる。
C++のライブラリはSTLを中核としている。STLではコンテナ(シーケンスの保持)、反復子(シーケンスの反復)、アルゴリズム(シーケンスの操作)、関数オブジェクトなどの機能を提供している。
(一部の内容でエキスパートCプログラミング―知られざるCの深層 (Ascii books)を参考に執筆しました。多くは自分で書きました。)