初始化时将函数作为构造函数参数传递给基类构造函数

时间:2016-12-02 12:03:28

标签: c++ class constructor callback function-pointers

#include <iostream>
#include<cstdio>
#include<typeinfo>

using std::cout;
using std::endl;

class foo;
class bar
{
    public:
        bar()
        {
        }
        bar(void (*getNextValue)(void)):memberFunctionPointer(getNextValue)
        {
        }
        void calltoderivedslass()
        {
            //  *memberFunctionPointer();
            ((bar*)this)->bar::memberFunctionPointer;
        }
        void (foo::*memberFunctionPointer)();
};

class foo : public bar
{
    public:
        foo( ):bar(static_cast<foo::*memberFunctionPointer>(&foo::hello))
        {
        }
        void hello()
        {
            printf("Hello \n\n");
        }
};
void byebye()
{
    cout << "bye" << endl;
}
int main()
{
    foo testfoo;
    //((testfoo).*(testfoo.memberFunctionPointer))();
    return 0;
}

错误:

classname.cpp: In constructor "bar::bar(void (*)())":
classname.cpp:15:68: error: cannot convert "void (*)()" to "void (foo::*)()" in initialization
classname.cpp: In constructor "foo::foo()":
classname.cpp:29:25: error: expected type-specifier
classname.cpp:29:25: error: expected ">"
classname.cpp:29:25: error: expected "("
classname.cpp:29:30: error: expected unqualified-id before "*" token
classname.cpp:31:2: error: expected "{" at end of input

期望:

我想初始化基类函数指针,初始化它指向派生类成员函数。我想在创建派生类的对象时初始化它。从基类我想使用获取的函数指针调用派生类函数。

提前感谢所有人。

2 个答案:

答案 0 :(得分:2)

对我来说看起来像虚拟方法:

class bar
{
    public:
        bar()
        {
        }
        void calltoderivedslass()
        {
            this->hello();
        }
        virtual void hello() = 0;
};

class foo : public bar
{
    public:
        foo( )
        {
        }
        void hello() override
        {
            printf("Hello \n\n");
        }
};

另一种方法可能是使用奇怪的重复模板模式(CRTP)来实现静态多态:

template<typename T>
class bar
{
    public:
        bar()
        {
        }
        void calltoderivedslass()
        {
            static_cast<T*>(this)->hello();
        }
};

class foo : public bar<foo>
{
    public:
        foo( )
        {
        }
        void hello()
        {
            printf("Hello \n\n");
        }
};

如果您真的希望保留指向成员函数的指针,可以考虑将std::function绑定到this

class bar
{
    public:
        bar()
        {
        }
        template<typename F>
        bar(F&& getNextValue):memberFunctionPointer(std::forward<F>(getNextValue))
        {
        }
        void calltoderivedslass()
        {
            this->memberFunctionPointer();
        }
        std::function<void()> memberFunctionPointer;
};

class foo : public bar
{
    public:
        foo( ):bar(std::bind(&foo::hello, this))
        {
        }
        void hello()
        {
            printf("Hello \n\n");
        }
};

我猜测:

void byebye()
{
    cout << "bye" << endl;
}
int main()
{
    bar testbar(byebye);
    testbar.calltoderivedslass(); // not a derived class, but it works
    return 0;
}

答案 1 :(得分:0)

bar的构造函数错误。

构造函数bar(void (*getNextValue)(void))不期望函数foo的成员函数指针,因此bar::memberFunctionPointer的类型无法初始化getNextValue

您需要将构造函数中的参数更改为void (foo::*getNextValue)(void)才能进行编译。

然而整体设计对我来说并不合适...所以我觉得@wasthishelpful的答案更有帮助; - )