首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于重载成员函数的成员函数指针

用于重载成员函数的成员函数指针
EN

Stack Overflow用户
提问于 2012-10-20 12:44:29
回答 2查看 649关注 0票数 1

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

代码语言:javascript
运行
复制
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){}
};

代码语言:javascript
运行
复制
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;
}

我的问题是:尽管我知道impl函数是一个成员函数指针(在本例中是&Base::onBeginEvent),但它真的有必要像void (Base::*func1)(int)void (Base::*func2)(int, int)那样定义它吗?

当只提供其中之一时,我显然得到的回复太少了。打电话的时候会有很多争论。我不想要变分函数或什么的,我想要有限的方法,可以提供的基础,以导出。派生只希望调用所提供方法的一个或任何子集。但我知道,它们只是在同一个符号上超载而已。我的目标不是让它与一些疯狂的解决方案一起工作,我只想知道,如果我能减少发布的代码。

全意式工作实例

在我的实际代码中,编辑 impl方法相当复杂,对于开始和结束都是一样的,只是在impl的末尾有不同的调用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-20 14:29:27

你说...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...,谁告诉你它们都是一个函数?仅仅因为两个函数有相同的名称,这并不意味着它们是相同的函数。他们的地址和每件事,除了他们的名字是不同的。所以它们是两个不同的函数,而不是一个函数。

票数 0
EN

Stack Overflow用户

发布于 2012-10-20 14:49:52

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

下面是一个例子:

代码语言:javascript
运行
复制
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,并创建EventHandlers的类层次结构,可能是EventBase和EventDerived。然后可以将EventHandlers注入EventManager (通过setEventHandler()方法)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12988564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档