微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在C ++中让静态成员函数调用非静态成员std :: function的正确方法是什么?

如何解决在C ++中让静态成员函数调用非静态成员std :: function的正确方法是什么?

我正在使用open62541库,该库的功能几乎都是静态的。我必须在open62541函数中编写一些回调函数,这些回调函数绑定到一些非静态函数

所以问题是我该怎么做:

A类的静态函数调用std :: function,它绑定到B类的非静态函数

为了使问题更简单,我举一个例子:

#include <iostream>
#include <functional>
using namespace std;

    namespace C {
    std::function<void(void)>C_foo;
    }
    class B
    {
    public:
        B()
        {
            C::C_foo=std::bind(&B::middleMan,this);
        }
        std::function<void(void)>B_foo;
        void middleMan()
        {
            B_foo();
        }
        static void talkTheJoke()
        {
            C::C_foo();
        }
        
    };
    class A
    {
    public:
        void Knock_knock()
        {
            std::cout<<"who's there?"<<std::endl;
        }
    };
    int main()
    {
        A m_A;
        B m_B;
        // response "who's there?"
        m_A.Knock_knock();

        m_B.B_foo=std::bind(&A::Knock_knock,m_A);
        
        //response "who's there?" again "
        B::talkTheJoke();
        
        return 0;
    }

有A类及其非静态成员函数A :: Knock_knock(),我希望B类的静态成员函数可以回调,并且其行为也与A :: Knock_knock()相同。

我在其中放置了B_foo作为回调函数,该函数将绑定A :: Knock_knock()。由于B :: talkTheJoke()是静态的,而B_foo不是静态的,因此似乎B :: talkTheJoke()无法调用B_foo。

所以我把命名空间C当作中间人,C中的std ::函数可以由静态函数B :: talkTheJoke()调用,它也可以绑定到非静态std ::函数B ::可以调用B_foo的middleMan()。

故事看起来像:

B :: talkTheJoke()----> m_B.B_foo-(std :: bind)-> m_A.Knock_knock()(X,无效)

B :: talkTheJoke()----> C :: C_foo()-(std :: bind)-> m_B.middleman()----> m_B.B_foo-(std ::绑定)-> m_A.Knock_knock()(O,works)

但是,这种解决方案确实很难看

这样做的正确方法是什么?

解决方法

#include <iostream>
using namespace std;

class A
{
public:
    void Knock_knock() {
        std::cout<<"who's there?"<<std::endl;
    }
};

class B
{
public:
    static void setA( A *a ) {
        m_A = a;
    }

    static void talkTheJoke() {
        if ( m_A != nullptr )
            m_A->Knock_knock();
    }

private:
    static A *m_A;
};

A* B::m_A = nullptr;

int main()
{
    A m_A;
    m_A.Knock_knock();

    B::setA( &m_A );
    B::talkTheJoke();
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。