我有关于使用函数对象继承的问题。
我想这一定是在Stack Overflow上被问到一个gazzilion时代,但是类似措辞的大量问题使得我几乎不可能找到任何东西。
假设我有一个基本抽象类:
class BinaryOperation
{
public:
virtual int operator()(int a, int b) = 0;
};
从中派生出两个新类:
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
使对象更容易发生内存泄漏的对象(我们必须手动{{1}对象)
delete
在不牺牲RAII优势的情况下,实现此功能的首选方法是什么?
答案 0 :(得分:4)
只需制作std::string
到std::function<int(int, int)>
的地图。这允许您取消任何公共基类,因为函数对象提供了polimorphism:
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中实现算术运算的函子,因此您不必自己实现Minus
和Plus
:
opMap["-"] = std::minus<int>();
opMap["+"] = std::plus<int>();