如何在它们之间分配和使用 2 个不同 类 的函数指针?

How can I assign and use function pointers of 2 different classes between among them?

我正在开发一个协议栈,我已经用 类 编写了不同的级别,它们具有用于连接它们之间不同级别的函数和函数指针。

我在管理和分配函数指针时遇到问题。情况类似如下(简化):

文件baseA.h:

class baseA
{
    public:
        virtual void fnc1(void)=0;
    void (B::*fnc2)(void)=NULL;
};

文件A.h:

class A:baseA
{
    public:
        void task(void);

        void fnc1(void);
        void (B::*fnc2)(void)=NULL;
};

文件A.cpp:

void A::task()
{
    if(this->fnc2!=NULL)
        this->fnc2();
}

void A::fnc1(void)
{
    //Do something
}

文件B.h:

class B
{
    public:
        void task(void);

        void fnc1(void);
        void (baseA::*fnc2)(void);
};

文件B.cpp:

void B::task(void)
{
    if(this->fnc2!=NULL)
        this->fnc2();
}

void B::fnc1(void)
{
    //Do something
}

主要功能:

main(void)
{
    A instA;
    B instB;

    instA.fnc2 = instB.fnc1;
    instB.fnc2 = instA.fnc1;

    while(1)
    {
        instA.task();
        instB.task();
    }
}

我有两个问题:

  1. 在函数 main 中,当我分配函数指针时,编译器 return 给出错误“cannot convert 'B::fnc1' from type 'void (B::)()' to type 'void (*)()'”(对于 instA.fnc2 = instB.fnc1;)和“cannot convert 'A::fnc1' from type 'void (A::)()' to type 'void (*)()'” (对于 instB.fnc2 = instA.fnc1;)。
  2. 当我在 task 函数内部使用函数指针时,编译器 return 给我错误“must use '.*' or '->*' to call pointer-to-member function in '((A*)this)->A::fnc2 (...)', e.g. '(... ->* ((A*)this)->A::fnc2) (...)'”。我曾尝试使用 (this->*fnc2)(); 但在这种情况下编译器 return 我的错误是“pointer to member type 'void (B::)()' incompatible with object type 'A'

我尝试搜索并应用在互联网上找到的不同建议,但我无法解决问题。 我的错误是什么?

成员函数指针语法并不简单,但你在这里有一个主要的理解问题:它是 某物 指向给定 class 的方法。这意味着:

  1. 你加载它时引用了 class 而不是(可能是多态的)对象
  2. 你在其 class
  3. 的一个对象上调用它

首先很简单,您必须在主程序中使用它:

instA.fnc2 = &B::fnc1;
instB.fnc2 = &baseA::fnc1; // and not A::fnc1 since fnc1 is only declared in baseA

对于第二点,您将需要 A 中的 B 对象(或引用或指针)和 A 对象(或引用或指针)B。为了简单起见,我将在这里使用指针:

class A:baseA
{
    public:
        void task(void);

        void fnc1(void);
        void (B::*fnc2)(void)=NULL;

        B* b;
};

void A::task()
{
    if(this->fnc2!=NULL && b != NULL)
        (b->*fnc2)();    // note the parentheses to avoid a syntax error
}

class B
{
    public:
        void task(void);

        void fnc1(void);
        void (baseA::*fnc2)(void);

        A* a;
};

void B::task(void)
{
    if(this->fnc2!=NULL && a != NULL)
        (a->*fnc2)();
}