重载成员函数的成员函数指针



注意:下面的代码示例不是真正的代码,真正的代码粘贴在这里要复杂得多,所以这个例子可能看起来很荒谬,但它并不重要。

struct Base
{
void beginEvent(int a)
{
impl(a, &Base::onBeginEvent, &Base::onBeginEvent);
}
void endEvent(int a)
{
impl(a, &Base::onEndEvent, &Base::onEndEvent);
}
void impl(int a, void (Base::*func1)(int), void (Base::*func2)(int, int))
{
//some complicated behavior
//...
(this->*func1)(a);
(this->*func2)(a, -a);
}
virtual void onBeginEvent(int a){}
virtual void onBeginEvent(int a, int negativeA){}
virtual void onEndEvent(int a){}
virtual void onEndEvent(int a, int negativeA){}
};

struct Derived : public Base
{
void onBeginEvent(int a) { std::cout << a << "n"; }
void onEndEvent(int a, int b) { std::cout << a << "==(-(" << b << "))n"; }
};
int main() 
{
Derived d;
d.beginEvent(3);
d.endEvent(9);
return 0;
}

我的问题是: 即使我知道它是一个成员函数指针(在这种情况下&Base::onBeginEvent),是否真的有必要以void (Base::*func1)(int)void (Base::*func2)(int, int)的方式定义impl函数?

当只提供其中之一时,我显然在打电话时得到的争论太少了。我不想要可变参数函数什么的,我想要有限数量的方法,它可以 Base 提供给派生。派生可能只希望调用所提供方法的一个或任何子集。但我知道,它们只是同一符号上的重载。我的目标不是让它与一些疯狂的解决方法一起工作,我只是想知道,我是否可以减少发布的代码。

:完整的 ideone 工作示例

编辑在我的真实代码中,impl方法非常复杂,开始和结束相同,只是在impl结束时调用不同...

如何将函数指针替换为多态行为,这实际上是一回事,但更 OO、更直观、更易于阅读。

下面是一个示例:

struct Base
{
void beginEvent(int a)
{
implBegin(a);
}
void endEvent(int a)
{
implEnd(a);
}
// Consider making the rest of the methods protected    
// protected:
// This is effectively a Template Method Design pattern
// This method may not be necessary, in which case just
// move the code to beginEvent()
void implBegin(int a)
{
onBeginEvent(a);
onBeginEvent(a, -a);
}
// This is effectively a Template Method Design pattern
// This method may not be necessary, in which case just
// move the code to endEvent()
void implEnd(int a)
{
onEndEvent(a);
onEndEvent(a, -a);
}
virtual void onBeginEvent(int a){}
virtual void onBeginEvent(int a, int negativeA){}
virtual void onEndEvent(int a){}
virtual void onEndEvent(int a, int negativeA){}
};
struct Derived : public Base
{
// Notice I defined these as virtual
virtual void onBeginEvent(int a) { std::cout << a << "n"; }
virtual void onEndEvent(int a, int b) { std::cout << a << "==(-(" << b << "))n"; }
};
int main() 
{
Derived d;
d.beginEvent(3);
d.endEvent(9);
return 0;
}

请注意,implBegin() 和 impleEnd() 可能不是必需的,并且 你可以在beginEvent()和endEvent()中做同样的事情 下面是指向模板方法设计模式的链接。

另一种方法是按原样定义 Base,但可以将其称为 EventManager,并创建 EventHandler 的类层次结构,也许是 EventBase 和 EventDerived。然后可以将 EventHandlers 注入到 EventManager 中(通过 setEventHandler() 方法)。

你说...the way it takes void (Base::*func1)(int) and void (Base::*func2)(int, int) even though I know that it is one member function pointer...,谁告诉你它们都是一个函数?仅仅因为 2 个函数具有相同的名称,并不意味着它们是相同的函数。 他们的地址和除了名字之外的所有东西都是不同的。所以它们是 2 个不同的功能而不是一个功能

最新更新