存储指向方法的派生指针

use*_*865 2 c++ inheritance function-pointers

我想创建一个类,它具有指向其方法之一作为属性的指针.然后应该有一个方法,用于设置此指针.

class A {
    private:
        void (A::*curr_f)();
    public:

        void set(void (A::*f)()) {
            curr_f = f;
        }
};
Run Code Online (Sandbox Code Playgroud)

当我尝试创建继承的类并将指针设置为其方法之一时,问题就开始了.

class B : A {
    public:
        void main() {
            set(&B::new_function);
        };
        void new_function() {};
};
Run Code Online (Sandbox Code Playgroud)

我得到的错误非常简单,但我仍然不知道如何解决这个问题.

error: no matching function for call to ‘B::set(void (B::*)())’
note: candidate is:
note: void A::set(void (A::*)())
note: no known conversion for argument 1 from ‘void (B::*)()’ to ‘void (A::*)()’
Run Code Online (Sandbox Code Playgroud)

mas*_*oud 6

你不能.A没有方法new_function,你对编译器撒谎.你有三种方法

1.

移动new_functionA并通过A::new_function(作为virtual优选).

class A
{
    void (A::*curr_f)();
public:
    void set(void (A::*f)())
    {
        curr_f = f;
    }
    virtual void new_function() {};
};

class B : A
{
public:
    void main()
    {
        set(&A::new_function);
    };
    void new_function() {};
};
Run Code Online (Sandbox Code Playgroud)

 

2.

转发B声明和存储B::*A:

class B;

class A
{
    void (B::*curr_f)();
public:
    void set(void (B::*f)())
    {
        curr_f = f;
    }
};

class B : A
{
public:
    void main()
    {
        set(&B::new_function);
    }
    void new_function() {}
};
Run Code Online (Sandbox Code Playgroud)

 

3.

您可以尝试基于模板的方式,例如奇怪的重复模板模式(CRTP).

template <typename D>
class A
{
    void (D::*curr_f)();
public:
    void set(void (D::*f)())
    {
        curr_f = f;
    }
};

class B : public A<B>
{
public:
    void main()
    {
        set(&B::new_function);
    }
    void new_function() {}
};
Run Code Online (Sandbox Code Playgroud)