1

関数オブジェクトの継承について質問があります。

これは、ここスタック オーバーフローで膨大な回数尋ねられたに違いないと思いますが、同様の言葉遣いの膨大な数の質問により、何かを見つけることはほぼ不可能です。

基本抽象クラスがあるとします。

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

次の 2 つの新しいクラスが派生します。

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;
    };
};

std::map同じクラスから派生したさまざまなファンクターに文字列をマップするために使用したいと思います。

私の最初のアプローチは

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

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

抽象クラスをインスタンス化できないため、明らかにこれは機能しませんでした。

基本クラスへのポインターを使用すると、問題なく動作しますが、見栄えが悪くnew、オブジェクトが必要なため、メモリリークが発生しやすくなります (deleteオブジェクトを手動で作成する必要があります)。

std::map<std::string, BinaryOperation*> operator_map;

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

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

RAII の利点を犠牲にすることなく、この機能を実現するにはどのような方法が望ましいでしょうか?

4

1 に答える 1

4

std::stringtoのマップを作成するだけstd::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ヘッダーMinusに実装するファンクターを提供するため、自分で実装する必要がないことに注意してPlusください。

opMap["-"] = std::minus<int>();
opMap["+"] = std::plus<int>();
于 2012-05-03T23:08:30.763 に答える