使用operator()()的虚拟关键字是否有意义? (函子)

时间:2011-09-13 14:49:12

标签: c++ inheritance virtual functor

考虑我的层次结构定义如下

class Strategy
{
public:
    virtual void Run();
};
class StrategyA : public Strategy
{
public:
    virtual void Run();
};
class StrategyB : public Strategy
{
public:
    virtual void Run();
};

我想知道我是否将run()替换为operator()是否有意义,以及从设计和效率角度来看是否有任何优势。

class Strategy
{
public:
    virtual void operator()();
};
class StrategyA : public Strategy
{
public:
    virtual void operator()();
};
class StrategyB : public Strategy
{
public:
    virtual void operator()();
};

谢谢

CV。

5 个答案:

答案 0 :(得分:11)

是。它完全有道理。

毕竟,任何操作符重载都是一个函数。它为语言添加了语法糖。有时,它们是必要的,但通常,它只是语法糖。

请注意,您必须以多态方式调用它(当然,如果您需要运行时多态性),并且有两种方法可以执行此操作:

  • 使用基类型的指针
  • 使用基本类型的参考

示例(demo),

struct A
{
   virtual void operator()() { cout << "A" << endl; }
};
struct B : A
{
   virtual void operator()() { cout << "B" << endl; }
};

int main() {
        B b;

        //using pointer
        A *ptr = &b;
        (*ptr)(); //clumsy!  - prints B

        //using reference
        A &ref = b;
        ref();   //better    - prints B

        //also correct
        b();  //prints B
        return 0;
}

如果您的函数模板写为:

template<typename Functor>
void call(Functor fun)
{
   (*fun)();
}

然后你可以使用这个函数,对于仿函数和常规函数,都可以:

void regular_function()
{
   cout << "regular_function" << endl;
}

B b;
call(&b);  //prints B
call(regular_function); //prints regular_function

演示:http://ideone.com/B9w16

答案 1 :(得分:5)

如前所述,是的,你可以。

以下有关可能的决胜局的其他信息。

对于虚拟方法,您可以访问类型为Strategy&amp;的对象。或战略*。如果您使用的是引用而不是指针,则无需阅读以下内容。否则,它可能是有意义的并且支持命名的虚方法。

StrategyA sA;
Strategy& s = sA;

s.Run(); //correct and readable
s(); //just as correct and readable

Strategy* ptr_s = &sA;
ptr_s->Run(); //correct and readable
(*ptr_s)(); // still correct but a bit clumsy

答案 2 :(得分:3)

做任何使你的代码最清晰的事情。可以接受仿函数的通用算法可以使用第二种方法 - 所以它是有意义的,但是具有可读性的平衡。

答案 3 :(得分:3)

是的,operator()只是特殊的功能名称。它也可以是virtual Run()

答案 4 :(得分:1)

我不明白为什么不。除了特定的上下文Run之外,函数名称并没有多说,如果你的类主要是模型函数,那么这似乎是一个合理的选择。