[C++] 実装の隠蔽:インターフェイスを使う
前回は、委譲を使うシンプルなPimplイディオムを取り上げた。今回は、よりオブジェクト指向(OOP)らしいインターフェイス(抽象クラス)を使った場合。
ヘッダファイル側:インターフェイスの宣言
#pragma once class ISample { public: virtual ~ISample(void){} virtual int getNum() const = 0; static ISample* createInstance(); static ISample* clone(ISample* base); };
定義ファイル側:実装
#include "ISample.h" class Sample : public ISample { // インターフェイスの実装 private: int num; public: Sample(const int num) : num(1) { } virtual ~Sample() { } int getNum() const { return num; } } ISample* ISample::createInstance() { return new Sample; } ISample* ISample::clone(ISample* base) { return new Sample(*base); }
要点
- 上記のとおりOOPとしてスマートなので、全体的にすっきりとする。
- インスタンスのコピーの場合も楽。
- ファイルのサイズが増えるか否かは実装依存。
- 仮想関数の呼び出しコストがかかる。
インターフェイスとFactoryパターンを使っているので、公開クラスの利用者側もOOPやデザインパターンをあらかじめくわしく知っている必要がある。
- 初心者向けではない。
Factoryパターンですべてのインスタンスを生成する以上、ポインタで受け取らざるを得ず、利用者側はそれを自分で管理する(deleteする)か、スマートポインタを使わなければならない。
- すべてのポインタを自分でdeleteするのは現実的ではないため、実質、ローカル変数でちょっと使うだけでもいちいちスマポを使うしかない。
全体的にOOPとしてはきれいだが、公開クラスを利用する側としてはあまり直感的でない。