C++ static class function + Function pointer issue

Started by
10 comments, last by Oluseyi 16 years, 3 months ago
SDL has a feature that allows you to set up a filter, to filter incoming events. The problem is, the function requires a parameter that's a pointer to a function, and the function I want to pass it is a member of a class. My IDE(Dev C++) tells me that I can't pass member functions, unless the function is static, but inside the function that would be static, I call a function that's a memember of the class. In short:
API_Function(int *functionPointer);

class MyClass
{
    MySetupFunction();
    MyOtherFunction();
    
    MyCallback();
    MyStaticCallback();
};

MySetupFunction()
{
    API_Function(MyCallback); //<-- Invalid: cannot convert 'int (MyClass::*)(params)' to 'int (*)(params)'
    API_Function(MyStaticCallback); //<-- Valid
}

MyCallback()
{
    MyOtherFunction(); <-- Valid
}

MyStaticCallback()
{
    MyOtherFunction(); <-- Invalid: cannot call member function 'MyClass::MyOtherFunction() without object
    this->MyOtherFunction(); <-- Invalid: `this' is unavailable for static member functions
}
I can't make my callback function from outside of the class either, becuase it calls class functions, nor can I pass a pointer to my class as a parameter, becuase that's not part of the API function. I suppose I could have a global pointer to the class, and set it after creating the class, but that seems sloppy. How would you go about this? Is there any way to get a pointer to the calling class from a static member function? I thought for sure the 'this' keyword would work, but I guess not. Alternatively, is there anyway to cast a member function to a static function when passing it to the API as a function pointer? There will only ever be one instance of the class at one time, if that helps any. I apreciate any help you can offer, if only a few keywords to google.
Advertisement
Are you familiar with Singleton pattern?

If you are not, shortly all you need to do is to create inside your class a static pointer to it self, initialize it in global scope to NULL,use assert(static pointer)in class constructor and set pointers address to this.Destructor is reverse process.Once you have done that, you can call:

pSingleton->AnyMemberFunction();

regards,
Savage
There is no way to do this without a global of some sort. Best you can do is to make the global local to a single file then, inside an anonymous namespace.

@SavageTSDN

Singleton is unnecessary here.

It is unnecessary pretty much everywhere, but what can 1 programmer do [sad]
Quote:Original post by SavageTSDN
Are you familiar with Singleton pattern?


Relevant reading

--

No, there's no way to get a pointer to the class from a static member unless you pass one in. That's the whole reason that you can get away with using a pointer-to-static-member as if it were a function pointer (as opposed to a pointer-to-member, cf C++ FAQ Lite).

What parameters does the callback take? In particular, does it take a void*? If so, then use that to pass in a relevant object, as in my recent, similar thread (SiCrane's response, third reply). (EDIT: A quick Google suggests this is a no go :-( )

EDIT: Goodness, I'm slow.
[TheUnbeliever]
Thanks guys, I googled 'Singleton pattern' and used that. If merely one of my classes has a pointer to itself, I don't think it'd be going overboard with singletons, and it's pretty clean looking as well.

What I'm doing now:
API_Function(int *functionPointer);class MyClass{    static MyClass *Self;        MySetupFunction();    MyOtherFunction();    MyStaticCallback();};MyClass *MyClass::Self = NULL;MyClass::MyClass(){    Self = this;}MySetupFunction(){    API_Function(MyStaticCallback);}MyStaticCallback(){    assert(MyClass::Self);    Self->MyOtherFunction();}

It works. Is there any reason why I shouldn't do it like this? Upon reading rip-off's reply, I could've made it a global in the class's cpp file. Hadn't thought of that, I was thinking of uglier method: (A global, with Set/Get functions)
MyClass myClass;SetClassPointer(&myClass);//Inside the static class function:MyClass *myclass = GetClassPointer();

Which was why I posted looking for a cleaner solution.

Thanks for the help guys.
Quote:Original post by Servant of the Lord
Thanks guys, I googled 'Singleton pattern' and used that. If merely one of my classes has a pointer to itself, I don't think it'd be going overboard with singletons, and it's pretty clean looking as well.

What I'm doing now:
*** Source Snippet Removed ***
It works. Is there any reason why I shouldn't do it like this? Upon reading rip-off's reply, I could've made it a global in the class's cpp file. Hadn't thought of that, I was thinking of uglier method: (A global, with Set/Get functions)
MyClass myClass;SetClassPointer(&myClass);//Inside the static class function:MyClass *myclass = GetClassPointer();

Which was why I posted looking for a cleaner solution.

Thanks for the help guys.


Read this topic,it might clear some things to you:

http://www.thescripts.com/forum/thread737451.html

Savage
Quote:Original post by SavageTSDN
Read this topic,it might clear some things to you:

http://www.thescripts.com/forum/thread737451.html

Savage


Singletons are globals. If you are going to use a global, don't be shy. This is what I would write:
// header fileclass MyClass{    MySetupFunction();    MyOtherFunction();        MyCallback();    static int MyStaticCallback( SDL_Event * );};void setupCallBack( std::auto_ptr<MyClass> );// source filenamespace {   std::auto_ptr<MyClass> callbackPtr;}void setupCallBack( std::auto_ptr<MyClass> ptr ){    callbackPtr = ptr;}int MyClass::MyStaticCallback( SDL_Event *event ){    assert(callbackPtr.get());    return callbackPtr->MyCallback(event);}
Quote:Original post by rip-off
Quote:Original post by SavageTSDN
Read this topic,it might clear some things to you:

http://www.thescripts.com/forum/thread737451.html

Savage


Singletons are globals. If you are going to use a global, don't be shy. This is what I would write:
*** Source Snippet Removed ***


Yes they are globals,but globals defined in a namespace(yes,I know that we can define global also in a namespace).Also when multithreading problem arises you cannot use just pure globals,but you can use singleton with locking..Singleton is somehow more elegant,and more reliable if you ask me.

Savage

I'm going to stick with what I currently have. Using static MyClass *Self inside the class as a private member looks cleaner to me than a global, and easier to read.(To me at least)

The only drawback is if a second one of my classes is constructed, the static pointer wouldn't function as planned, but it's easy enough to protect against that by a flag to check against (Something like bool ClassActive), or even checking if the pointer is no longer NULL.

Thanks for your help guys, I was at a loss of what to do.
Quote:Original post by Servant of the Lord
I'm going to stick with what I currently have. Using static MyClass *Self inside the class as a private member looks cleaner to me than a global, and easier to read.(To me at least)

The only drawback is if a second one of my classes is constructed, the static pointer wouldn't function as planned, but it's easy enough to protect against that by a flag to check against (Something like bool ClassActive), or even checking if the pointer is no longer NULL.

Thanks for your help guys, I was at a loss of what to do.


If you create another instance of your class assertion would fail in constructor.
Also,if you just used a simple global,it members would probably get owerwriten when you use second instance,therefore singleton is more safer.

regards,
Savage

This topic is closed to new replies.

Advertisement