2012-05-03 8 views
1

関数オブジェクトでの継承に関する質問があります。派生クラスの関数呼び出し演算子を呼び出すときにポインタを避ける

これはスタックオーバーフローでgazzilionの時間を尋ねられているはずですが、同様の文言で膨大な数の質問があれば、私は何かを見つけるのがほぼ不可能になります。

私は基本抽象クラスがあるとします。私は由来している様々なファンクタに文字列をマップするためにstd::mapを使用したい

class Plus : public BinaryOperation 
{ 
public: 
    virtual int operator()(int a, int b) 
    { 
     return a + b; 
    }; 
}; 

class Minus : public BinaryOperation 
{ 
public: 
    virtual int operator()(int a, int b) 
    { 
     return a - b; 
    }; 
}; 

:二つの新しいクラスが派生

class BinaryOperation 
{ 
public: 
    virtual int operator()(int a, int b) = 0; 
}; 

、そこからの同じクラス:

私の最初のアプローチは

std::map<std::string, BinaryOperation> operator_map; 
operator_map["+"] = Plus(); 
operator_map["-"] = Minus(); 

operator_map["-"](5, 2); 

抽象クラスをインスタンス化できないため、明らかにこれは機能しませんでした。私は、基本クラスへのポインタを使用する場合は

(私たちはを手動 deleteオブジェクトを持っている)それだけで正常に動作しますが、それはclumsier見て、私たちは newにオブジェクトを持っているので、メモリリークにそれが起こりやすくなり、その
std::map<std::string, BinaryOperation*> operator_map; 

operator_map["+"] = new Plus(); 
operator_map["-"] = new Minus(); 

std::cout << (*operator_map["-"])(5, 2) 

RAIIの利点を犠牲にすることなくこの機能を達成するための好ましい方法は何ですか?

+0

あなたはスマートポインタを使用するときにあまりにも多くのポインタを心配する必要はありません。) – chris

+0

まあ、私は広範囲にそれらを使用し、知っています。私はちょうど彼らが何か明らかにそう簡単に必要でないことを願っています:) – Tibor

答えて

4

std::stringstd::function<int(int, int)>の地図を作成してください。

struct Plus { 
    int operator()(int a, int b) const{ return a+b; } 
}; 

struct Minus { 
    int operator()(int a, int b) const{ return a-b; } 
}; 

int main() 
{ 
    std::map<std::string, std::function<int(int,int)>> opMap; 
    using namespace std::placeholders; 

    opMap["-"] = Minus(); 
    opMap["+"] = Plus(); 

    std::cout << opMap["-"](5,2) << std::endl; 
    std::cout << opMap["+"](5,6) << std::endl; 
} 

注標準ライブラリはfunctional headerで算術演算を実装ファンクタを提供し、あなたが実装する必要はありません:関数オブジェクトがpolimorphismを提供するので、これは、あなたは、任意の共通の基底クラスを廃止することを可能にしますMinusPlus自分自身:

opMap["-"] = std::minus<int>(); 
opMap["+"] = std::plus<int>(); 
+0

OK、それを試して、それは動作します。このように定義したら、ベースクラスで何をしますか? – Tibor

+0

@Tiborでは、基本クラスを完全に忘れて、別のものに必要な場合を除き、デザインから削除することができます。 – juanchopanza

+0

@Tiborサンプルコードを追加しました。 – juanchopanza

関連する問題