i have a BaseClass and a DerivedClass. i need the BaseClass to register a glut callback, but i need the DerivedClass to determine what the callback does.

heres the code:

(.h)

class BaseClass
{
public:
         BaseClass();
         ~BaseClass();

protected:
         static void _renderCallback(void);

         virtual void Render();
};

(.cpp)

BaseClass::_renderCallback(void)
{
          Render();
}

BaseClass::Render()
{
           //override me in the DerivedClass !          
}

i understand that if the callback is within a class, it must be declared as static, and it cannot be virtual. but of course i get compile time errors with this code -

"in function 'BaseClass::_renderCallback(void)': 
cannot call member function 'BaseClass::Render' without object".

so how to enable the callback to call a function that can be overriden in the derived class?

Recommended Answers

All 9 Replies

well ive been doing a bit of reseach on this and it looks nasty. declaring the callback as static gets rid of the 'this' pointer, (so registering it as a callback is fine), but because of this it cant access any of the other members of the class! so its pretty useless.

so i guess this changes the question slightly. how to make the static function access the other members of the class? can it be done?

so i guess this changes the question slightly. how to make the static function access the other members of the class? can it be done?

You can't. Static members are exactly that: static. They're the same throughout all instances of the class; in fact they don't need an instance to be used.

So let's say you call a static function. It's not going to have an object, so how the heck is it supposed to know which object to access from, even if you could do such a thing?

yes i see. bummer.

cheers though.

One way to get a static member access non-static methods is thru a static or global pionter or reference to the desired instance. Then the static member uses that pointer to access non-static methods and data objects.

Another method is to make static all the methods and objects that the static method needs to access.

Another method is to make static all the methods and objects that the static method needs to access.

But I guess that would beat the purpose of designing class for creating objects since each object created would have the same thing inside of it (the member variables being static).

But I guess that would beat the purpose of designing class for creating objects since each object created would have the same thing inside of it (the member variables being static).

Yes it would -- but in some cases I can think of there is only a single instance of the class anyway and making everything static would only be useful in such a case.

@Ancient Dragon => That is the right way of doing it. Declare your callback function to take the this pointer. Same mechanism used for thread functions as well.
But in this case caller has to get the this pointer. If there is a possibility to change the callback interface there is a cleaner soln..

Coming to the problem.
- There is no easy soln. if callback interface is fixed.
- One good/clean soln would be register the base class object as callback object instead of a callback function. This is more on lines of how Java does it. In most cases one needs to implement a callback interface in a Impl class, create an object of this Impl class and register the object for callback (instead of function). But all this is possible only if you have control over how to define the callback interface.

@Ancient Dragon => That is the right way of doing it. Declare your callback function to take the this pointer. Same mechanism used for thread functions as well..

If you are writing your own interface then you may be able to use non-static class methods for callback functions. I've see this coded a couple times but don't recall exactly how its done. The problem is when you have to pass callback functions to a function that you did not write, such as win32 api and other library functions.

Finally I think I found a soln. Let me know if it does what you need..
It's like a hybrid soln of the one using callback functions and one using callback objects. Idea is to register the derived class obj with base class. Advantage is base class's _renderCallback() can call a (non-static) function of the derived class.

#include <iostream>
#include <conio.h>    //getch()

using namespace std ;
//------------------------------------------------
class BaseClass
{
public:
    BaseClass() {}
    ~BaseClass() {}

    static void _renderCallback(void)
    { derivedClassObjPtr->Render(); }

protected:
    void set_derivedClassObjPtr( BaseClass* ptr )
    { derivedClassObjPtr = ptr ; }

    virtual void Render() = 0 ;

private:
    static BaseClass* derivedClassObjPtr ;
};

BaseClass* BaseClass::derivedClassObjPtr = NULL ;
//------------------------------------------------

class DerivedClass : public BaseClass
{
public:
    DerivedClass()
    { set_derivedClassObjPtr( this ) ; }
    ~DerivedClass() {}

protected:
    virtual void Render()
    { cout << "Inside DerivedClass::Render()" << endl ; }
};
//------------------------------------------------

typedef void(*t_CallBackFunction)() ;
t_CallBackFunction theCallbackFunc ;

void callback_registration_function( t_CallBackFunction func )
{ theCallbackFunc = func ; }

void trigger_callback()
{ theCallbackFunc(); }
//------------------------------------------------

int main ()
{
    DerivedClass obj ;
    callback_registration_function( BaseClass::_renderCallback ) ;
    trigger_callback() ;

    //-----------------------
    getch() ;
    return 0;
}
//------------------------------------------------
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.