Return to Snippet

Revision: 6492
at May 24, 2008 13:01 by tkf


Initial Code
#include <iostream>
//------------------------------ あらゆるfunctorの元
class FunctorBaseClass{
public:
  // 仮想関数で実行のされかたのみを定義する.
  // (ここでは()演算子のオーバーロード)
  virtual double operator()(double val){};
};
//------------------------------ 先のクラスの継承
template <class TClass>
class SpecificFunctor : public FunctorBaseClass{
public:
  // pt2func : メンバ関数へのポインタ
  double (TClass::*pt2func)(double);
  // pt2obj  ; インスタンスへのポインタ
  TClass* pt2obj;
  SpecificFunctor(TClass* _pt2obj, double(TClass::*_pt2func)(double)){
    pt2obj  = _pt2obj;  // TClassインスタンスへのポインタをメンバ変数へ代入
    pt2func = _pt2func; // TClassメンバ関数  へのポインタをメンバ変数へ代入
  }
  virtual double operator()(double val){
    // インスタンス.メンバ関数(引数) の形で実行
    return (*pt2obj.*pt2func)(val);
  }
};
//------------------------------ 処理(1)
class PlusOne{
public:
  double func(double val) {
    return val+1;
  }
};
//------------------------------ 処理(2)
class PlusA{
public:
  double a;
  PlusA(double _a) {
    a = _a;
  }
  double func(double val) {
    return val+a;
  }
};
//------------------------------ 使用例
int main(){
  PlusOne obj1;
  PlusA   obj2(2);

  // インスタンスと実行するメンバ関数を引数にとってインスタンス作成
  SpecificFunctor< PlusOne > specFunc1(&obj1, &PlusOne::func);
  SpecificFunctor< PlusA   > specFunc2(&obj2, &PlusA  ::func);
  // 継承元のクラスのポインタの配列に代入出来る
  FunctorBaseClass* vTable[] = { &specFunc1, &specFunc2 };
  // 実行してみる
  std::cout << "PlusOne::func(1) = "
	    << (*vTable[0])(1) << std::endl;
  std::cout << "PlusA  ::func(1) = "
	    << (*vTable[1])(1) << std::endl;
  return 0;
}

Initial URL


Initial Description
参考:
1. http://www.newty.de/fpt/functor.html
-- ほとんど、このコードにコメントを加えただけですw
2. http://d.hatena.ne.jp/nurs/20080125/1201278130
-- 最初このページを見つけたのですが、この方法だと実行時にファンクタ(関数オブジェクト)を作って、配列に入れて処理を切り替え、ってことが出来ないと思ったので、このコードを書きました。
3. http://www.mokehehe.com/assari/index.php?C%2B%2B%2F%A5%E1%A5%F3%A5%D0%B4%D8%BF%F4%A4%CE%A5%DD%A5%A4%A5%F3%A5%BF
-- 似てるかも

Initial Title
C++でFunctorによる処理の切り替え

Initial Tags


Initial Language
C++