More C++ Idioms/名前付きコンストラクタ(Named Constructor)
名前付きコンストラクタ(Named Constructor)
編集
意図
編集- クラスのオブジェクトを生成する可読性が高く直感的な方法を提供する。
- クラスのオブジェクトを生成する際に特定の制約を強制する。
別名
編集動機
編集C++ では、コンストラクタはパラメータの型、順序、数によってのみ互いに区別される。もちろん、クラスが複数のコンストラクタを持つ時、それぞれのコンストラクタは異なる目的を持っている。しかし、C++ ではクラスのインタフェースに対して 意味的な 違いを表現することは困難である。なぜなら全てのコンストラクタは同じ名前を持ちパラメータによってのみ区別されうるからである。パラメータの型、順序、数のみが異なる多数のコンストラクタ呼び出しを伴うコードを読むことは、クラスのオリジナルな作者以外には非常に非直感的なものとなる。名前付きコンストラクタ(Named Constructor)イディオムはこの問題に対処する。
解法とサンプルコード
編集名前付きコンストラクタ(Named Constructor)イディオムは、コンストラクタの代わりにオブジェクトを生成する意味のある名前を持った一組の静的メンバ関数を利用する。コンストラクタは private か protected でクライアントは public な静的関数のみにアクセスできる。その静的関数群は 名前付きコンストラクタ(named constructor) と呼ばれ、オブジェクトを生成するそれぞれ独自の方法と、それぞれ異なった直感的な名前を持つ。以下の例を考えてみよう。
class Game
{
public:
static Game createSinglePlayerGame() { return Game(0); } // 名前付きコンストラクタ
static Game createMultiPlayerGame() { return Game(1); } // 名前付きコンストラクタ
protected:
Game (int game_type);
};
int main(void)
{
Game g1 = Game::createSinglePlayerGame(); // 名前付きコンストラクタの利用
Game g2 = Game(1); // 名前付きコンストラクタなしでの複数プレイヤーゲーム (コンパイルされない)
}
上記クラスにおいて名前付きコンストラクタ(Named Constructor)イディオムなしの場合、Game(1) と Game(0) が何を意味するのか把握することは難しい。このイディオムはその意図をはっきり明確にする。さらに、このイディオムによりオブジェクトの生成プロセスに特定の制約を課することができる。例えば、名前付きコンストラクタが常に new を使って動的にオブジェクトを作成するようにできる。そのような場合、リソースの返値(Resource Return)イディオムも有用となるだろう。