[C++] 実装の隠蔽:インターフェイスを使う

前回は、委譲を使うシンプルなPimplイディオムを取り上げた。今回は、よりオブジェクト指向(OOP)らしいインターフェイス(抽象クラス)を使った場合。

ヘッダファイル側:インターフェイスの宣言
[cpp]
#pragma once

class ISample
{
public:
virtual ~ISample(void){}

virtual int getNum() const = 0;

static ISample* createInstance();
static ISample* clone(ISample* base);
};
[/cpp]

定義ファイル側:実装
[cpp]
#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); }
[/cpp]

要点

  • 上記のとおりOOPとしてスマートなので、全体的にすっきりとする。
  • インスタンスのコピーの場合も楽。
  • ファイルのサイズが増えるか否かは実装依存。
  • 仮想関数の呼び出しコストがかかる。

インターフェイスとFactoryパターンを使っているので、公開クラスの利用者側もOOPやデザインパターンをあらかじめくわしく知っている必要がある。

  • 初心者向けではない。

Factoryパターンですべてのインスタンスを生成する以上、ポインタで受け取らざるを得ず、利用者側はそれを自分で管理する(deleteする)か、スマートポインタを使わなければならない。

  • すべてのポインタを自分でdeleteするのは現実的ではないため、実質、ローカル変数でちょっと使うだけでもいちいちスマポを使うしかない。

全体的にOOPとしてはきれいだが、公開クラスを利用する側としてはあまり直感的でない。