繁体   English   中英

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

[英]Member function pointer for overloaded member function

注意:以下代码示例不是真实的代码,将真实代码粘贴到此处要复杂得多,因此该示例可能看起来很荒谬,但这并不重要。

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

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

如果只提供其中之一,我显然得不到太多响应。 调用时会产生很多争论。 我不需要可变函数或其他函数,我想要Base可以提供给Derived的有限数量的方法。 派生可能只希望调用提供的方法中的一个或任何子集。 但是我知道,它们将只是同一符号上的重载。 我的目标不是让它与某些疯狂的解决方法一起工作,我只是想知道,是否可以减少发布的代码。

完整的ideone工作示例

在我的实际代码中编辑 Thme impl方法非常复杂,在impl的末尾使用不同的调用来进行相同的开始和结束操作。

如何用多态行为替换函数指针,这实际上是同一件事,但是更多的面向对象,更直观,更易于阅读。

这是一个例子:

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()中做同样的事情。这是Template Method Design模式的链接。

另一种方法是按原样定义Base,但可以将其称为EventManager,并创建EventHandlers的类层次结构,可能是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种不同的功能而不是一种功能

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM