WrapperクラスとTemplate化

c++でWrapperクラス・Template化の必要性

 例えば、あるクラスXにもう一つのクラスYのオブジェクトをメンバ変数として持たせたいとする。その場合、元のクラスYのオブジェクトに影響を及ぼさないように、クラスXの初期化の際に、クラスYのオブジェクトをdeep copyしてメンバ変数として持たせる。deep copyはnew演算子により行われるので、deleteにより明示的にメモリを解放する(クラスXのデストラクタをオーバーロードする)必要がある。そうしなければ、クラスXのオブジェクトがスコープを抜けた際にdeep copyしたクラスYのメモリが解放されず、メモリを圧迫することになる(メモリリークにつながる)。そのためクラスX(とその継承クラス)にデストラクタを実装し、毎回クラスYのオブジェクトを明示的にメモリ解放する必要がある。しかしこれではクラスXを継承する度に毎回余分な実装をする必要が出てきて、Open for Extension Closed for modificationのルールに反する。そこで解決策として、クラスYのWrapperクラス(以下WrapperYクラス)を用意することが考えられる。WrapperYクラスにクラスYのメモリハンドリングを任せておき、クラスXからはこのWrapperYを呼ぶことで、クラスXのオブジェクトがスコープを抜けた際に、WrapperYクラスのデストラクタが呼び出され、クラスYオブジェクトのメモリが自動で解放される。このようにWrapperクラスはメモリハンドリングが可能で余分な実装を減らすことに役立つ。  Wrapperクラスの役割は上記がメインのため、あるクラスに対するWrapperクラスの実装は毎度同じようなものになる。例えば、クラスXに、クラスY、クラスZのオブジェクトをメンバ変数として持たせたいとする。その際、WrapperYクラスとWrapperZクラスを用意すればいいのだが、ほぼ同じ実装となるため毎回Wrapperクラスの実装を書くのは煩わしい。そこで役に立つのがTemplateである。Templateを実装すればtemplate<classY> 、template<classZ>のように呼び出すことで、WrapperY、WrapperZを実装した場合と同様の挙動(メモリハンドリング)が可能となる。

rule of three

もしcopy constructor, copy assignment operator, destructorのうち一つでも必要であれば3つ全部必要であるというルール。これは単にcopy constructor, copy assignment operatorを使う時ってdeep copyが必要になるわけやから、オブジェクトをコピーする際には、コンストラクト時にnew演算子を呼ぶわけで、そうなるとdestructorもオーバーロードしてdelete演算子を呼び出す必要がある。逆も然り。