ユーザもしくは設定ファイルから読み込んだ順番どおりに処理をする方法。



【サンプル】

#include <cstdlib>
#include <iostream>


using namespace std;


//コマンド基底クラス
class cmd
{
public:
virtual ~cmd(){};
//virtualにするのがミソです。
virtual void exec()=0;
};


//泣くクラス
class cry: public cmd
{
public:
virtual ~cry(){};
//
virtual void exec()
{
cout << "えーん" << endl;
};
};


//笑うクラス
class laugh: public cmd
{
public:
virtual ~laugh(){};
//
virtual void exec()
{
cout << "あはは" << endl;
};
};



int main(int argc, char *argv[])
{
//配列作成
cmd* c[2];
//処理の実体クラスの作成
cry exec_cry;
laugh exec_laugh;

//実際には、ユーザの入力を受け取った順番で配列に設定すればよいです。

//親クラスへのキャストをしています。
c[0] = (cmd*)&exec_cry;
c[1] = (cmd*)&exec_laugh;

//設定した順番に処理を実行する
for(int i=0; i<2; ++i){
c[i]->exec();
}


system("PAUSE");
return EXIT_SUCCESS;
}



【出力】
えーん

あはは



【説明】

virtual を使用すると、親クラスへキャストしたときも、子クラスのメソッドが呼ばれます。

配列へのクラス代入の順番を変えるだけで、実行される処理の順番が変わります。

これを利用すれば、上記のようにVBのマクロみたいなことができます。



漏補

漏:

上記例では簡易なサンプルということで、cryなどをnew しませんでした。

普通は、cry, laughをnewして c[]に代入して、最後にループで、delete c[i]; します。

デストラクタにvirtual を使用しないと、親クラスのデストラクタが呼ばれます。

この場合、子クラスのデストラクタにメモリ解放処理を入れていても、親のデストラクタが

呼ばれるので、メモリリークや終了処理が未完了になるバグになってしまいます。


補:

上記のように virtualでメソッドを使用する場合、以下のルールを守る。

 ・親クラスのデストラクタは、vitualにして、処理を書き込まない。



参考:

デザインパターン:コマンドパターン