掲題について、C++を使っている人の中にはC言語から初めた方が実に多い。
ただ多くの方がC言語ベースで、オブジェクト指向やC++のメリットを考えずに、ただ業務などでC++のコンパイラを使っているからC++が出来ると考えている。
ここで改めてC++のメリットを2点挙げる。
1.オブジェクト指向
2.template library
1については、何冊の本にもなるほどの情報になりパターンなど発展した考え方も特に重要なので気が向いた時に追々に書いていきたいが2の考え方は慣れるまで難しいが慣れてしまえばとても有用なので少し書いていきたいと思う。
以下ひとつのtemplateの定義である。
/* ソース1 */
#ifndef SINGLETON_TEMPLATE_H
#define SINGLETON_TEMPLATE_H
template < class T >
class SingletonTemplate {
private :
//唯一のインスタンス
static T Data;
//コンストラクタ
SingletonTemplate(){};
SingletonTemplate(SingletonTemplate<T> &){};
public:
//デストラクタ
~SingletonTemplate(){};
//インスタンスの取得
static T & getInstance(){ return SingletonTemplate::Data ; };
};
template < class T >
T SingletonTemplate<T>::Data ;
#endif
これはGOFのsingletonパターン(クラスのインスタンスがひとつしか生成されないような実装)の変形パターンである。
要はコンストラクタとデストラクタをprivateに隠蔽しstaticに定義されている変数はひとつしか生成されない。
このクラスのgetInstanceをコールすることによりstatic変数を取得できる。
といったパターンである。
singletonについてはnetに情報が腐るほど転がっているのでそれを参考にしていただきたい。
このコードではtemplateの部分が重要なのであるが、この記述のルールは「class Tと言うデータ型を仮に定義してあり実際に利用する際に後から定義する」ということである。
利用する際には仮のデータ型を指定する必要があるので以下のような記述になるであろう。
/* ソース2 */
class a{
public:
int data1;
float data2;
};
a & val = SingletonTemplate< a >::getInstance();
ではこのときにtemplateの実装のソースをどう読めばよいかと言うと単純にtemplate定義のTの部分を置き換えればよいのである。
/* ソース3 */
class SingletonTemplate {
private :
//唯一のインスタンス
static a Data;
//コンストラクタ
SingletonTemplate(){};
SingletonTemplate( a & ){};
public:
//デストラクタ
~SingletonTemplate(){};
//インスタンスの取得
static a & getInstance(){ return SingletonTemplate::Data ; };
};
a SingletonTemplate::Data ;
a & val = SingletonTemplate::getInstance();
それこそdefineでプリプロセッサが置き換えるようなイメージである。
ソース1のデータ型を実際に記述したのがソース3である。
そしてtemplateの記述ルールさえ把握しておけばソース3からソース1への記述を変更することも当然出来るようになる。
このソース3からソース1への修正が出来るようになればコードの再利用が格段にアップするようになる。
私の過去の実装をいくつか例にあげてみても以下のようなものが簡単に出てくる。
1.Thread処理についてThreadでの主処理やデータは変わってくるがThreadの生成や同期処理については共通であるためThread処理のクラスは仮定義して共通処理はtemplateとして実装しておく。
2.singletonはデータ型が変わるごとにsingletonのクラスを改めて定義するのではなくデータ型を仮定義してsingletonの主要ルールはtemplateとして実装しておく。
3.通常C++ではmew,deleteを使うがwindowsではバッファを利用しないファイル読み込みなどVirtualAllocを使いたいケースもある。
メモリーの取得方法についてどの方法を使うかは仮定義として、メモリーのサイズの管理や拡張、最終的な破棄についてはtemplate実装しておく。
など数多くのケースで利用している。
また、c++で標準で持っているSTLのかなり有益であるので、これを機会にみなさんにもtemplateを見直すもしくは改めて勉強することをお奨めする。