考虑我的层次结构定义如下
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。
答案 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
答案 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
之外,函数名称并没有多说,如果你的类主要是模型函数,那么这似乎是一个合理的选择。