2
#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;
}

Error:

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

Expectations:

I want to initialize the base class function pointer to initialize it points to derived class member function. I want to initialize that while creating object of derived class. From base class i want to call derived class function using the acquired function pointer.

Thanks in advance for all.

rocambille
  • 15,398
  • 12
  • 50
  • 68
  • 1
    If you use OOP correctly there is no need to use function pointers... Consider the programmers who will have to maintain you code.. – Ol1v3r Dec 02 '16 at 12:09
  • yeah,there is a requirement to use function pointer. A callback has to be called when some error occurs in a DB reading, So i am in need of function pointer, Not to make difficulty in maintaining the code. Thanks :) – Kiruthika Palanivelu Dec 06 '16 at 15:41

2 Answers2

2

Looks like virtual methods to me:

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");
        }
};

An other way may be to use the Curiously Recurring Template Pattern (CRTP) to achieve static polymorphism:

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");
        }
};

If you really want to keep pointers to member functions, you may consider std::function bound to 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");
        }
};

With an extended usage I'm guessing:

void byebye()
{
    cout << "bye" << endl;
}
int main()
{
    bar testbar(byebye);
    testbar.calltoderivedslass(); // not a derived class, but it works
    return 0;
}
Community
  • 1
  • 1
rocambille
  • 15,398
  • 12
  • 50
  • 68
  • thank you for your answer, When i have use your code, i am getting errors as below, – Kiruthika Palanivelu Dec 02 '16 at 12:26
  • @KiruthikaPalanivelu There is no "errors as below" ^^ Anyway, did you add `#include ` to use `std::function`? – rocambille Dec 02 '16 at 12:30
  • thank you for your answer, When i have use your code, i am getting errors as below, error: expected â,â or â...â before â&&â token error: âfunctionâ in namespace âstdâ does not name a type In constructor âbar::bar(F)â: error: class âbarâ does not have any field named âmemberFunctionPointerâ error: âforwardâ is not a member of âstdâ error: expected primary-expression before â>â token error: âgetNextValueâ was not declared in this scope In member function âvoid bar::calltoderivedslass()â: error: âclass barâ has no member named âmemberFunctionPointerâ – Kiruthika Palanivelu Dec 02 '16 at 12:36
  • @KiruthikaPalanivelu did you include `functional`? What compiler are you using? My code needs C++11 support – rocambille Dec 02 '16 at 12:40
  • Thread model: posix gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) Yes!! I got compilation terminated when i uses that. kiru4.cpp: In constructor âfoo::foo()â: kiru4.cpp:29:20: error: âbindâ is not a member of âstdâ – Kiruthika Palanivelu Dec 02 '16 at 12:48
  • @KiruthikaPalanivelu I don't think gcc 4.6.3 has enough C++11 support. But you can try virtual methods or CRTP ;) – rocambille Dec 02 '16 at 12:54
  • 16:14: error: expected â,â or â...â before â&&â token 23:9: error: âfunctionâ in namespace âstdâ does not name a type In constructor âbar::bar(F)â: 16:31: error: class âbarâ does not have any field named âmemberFunctionPointerâ 16:53: error: âforwardâ is not a member of âstdâ 16:67: error: expected primary-expression before â>â token 16:69: error: âgetNextValueâ was not declared in this scope In member function âvoid bar::calltoderivedslass()â: 21:19: error: âclass barâ has no member named âmemberFunctionPointerâ In constructor âfoo::foo()â: 29:20: error: âbindâ is not a member – Kiruthika Palanivelu Dec 02 '16 at 13:14
0

Your constructor for bar is wrong.

The constructor bar(void (*getNextValue)(void)) does not expect a member function pointer of a function of foo and therefore initializing bar::memberFunctionPointer is not possible with the type of getNextValue.

You need to change the parameter in the constructor to void (foo::*getNextValue)(void) for this to compile.

Yet the overall design does not really seem right to me... So I think the answer of @wasthishelpful is more helpful ;-)

Simon Kraemer
  • 5,700
  • 1
  • 19
  • 49
  • That error was fixed:) but still this error 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 – Kiruthika Palanivelu Dec 02 '16 at 12:37
  • Simon-kraemer This is my derived class constructor i am trying to pass function pointer to base class constructor foo( ):bar(static_cast(&foo::hello)) please correct me if i am wrong. – Kiruthika Palanivelu Dec 02 '16 at 12:40
  • Yes you do, but the receiving side implicitly converts the member function back. BTW: You don't need to cast in foo. `&foo::hello` is already the correct type. Have a look at this: https://godbolt.org/g/Bw72R1 And please check the other answer as it is definitely the better solution! – Simon Kraemer Dec 02 '16 at 12:59
  • Thanks -Simon Kraemer once again. Compilation error is fixed. But i am not getting my desired output. testfoo.calltoderivedslass(); i want my derived class function hello() to be called, but that is not happening. Is any thing wrong with this syntax, ((bar*)this)->bar::memberFunctionPointer; – Kiruthika Palanivelu Dec 02 '16 at 13:11