Skip to main content
gamedev.net
🔒 Locked

Type safety with function pointers question

Started by RobertC Dec 20, 2002 at 6:16 AM 2 replies 150+ views
Original Post
RobertC
RobertC
Please excuse me if this sounds confusing, it makes sense in my head . The only way I can explain this is to show you some code: I have a class: myClass{ public: void setFunction(void(*)(unsigned int)); } Now, in another class I have: otherClass { public: void functionToBeCalled(unsigned int); void initFunction(); private: myClass *blah; } initFunction() { blah->setFunction(functionToBeCalled); } This, of course does not work, I have tried many hack ways but to no avail. Now, the only way I have been able to solve this is to create a static member variable that points to the this pointer and then use this with a wrapper function: Now it becomes: otherClass { public: void functionToBeCalled(unsigned int); void initFunction(); static otherClass *otherPtr; private: myClass *blah; } initFunction() { blah->setFunction(wrapperFunc); } void wrapperFunc(unsigned int) { otherPtr->functionToBeCalled(int); } Surely there must be another way that I have missed/don''t know about? Thanks in advance.
Paradigm Shifter
Paradigm Shifter
You wan''t to check out "pointers to members". I''m not 100% sure of the syntax, but it involves .* and ->*


"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
LilBudyWizer
LilBudyWizer
There are occasions when you need to call a member function through a pointer, but in most cases virtual functions and a common base class defining the interface would do exactly what is needed. This seems to be a case where you should be using a polymorphic base class.

It seems easiest just to explain how virtual functions are implemented. First an analogy. You have a pointer to a structure, call it struct1, and the first member of that structure is another structure, call it struct2. Now you have a function that takes a parameter pointer to struct2. All you have to do to call that function with the pointer you have is to cast that pointer to a pointer to struct2, i.e. it already points to a struct2 that just happens to be inside a struct1. That is the basic idea of how inheritence in general is implmented. You can use a derived class as an instance of the base class because all the members of the base class come first making all the offsets correct.

When you define a virtual function a data member is added to the class. It is a pointer to what is called a vtable. The vtable is a table of pointers to the virtual functions. The vtable for a derived class is distinct from the base class, but starts with pointers to the same functions more or less. Assuming the derived class actually imlements the virtual function the pointer actually points to the derived classes implementation. When you call a virtual function through a pointer to the base class a specific offset in the vtable is loaded and called. If it is an actual instance of the base class then that is the base classes vtable and the function points to the implementation in the base class. If it is an instance of the derived class then that is the vtable for the derived class and you call the implementation in the derived class. The vtable is like the structure described above. Even though the name is discarded conceptually both the base and derived class''s vtable start with pointers to functions taking the same types of parameters and the same name. The only differance is that the derived class may actually point to a differant function though it can point to the same function if it didn''t implement the virtual function. Also the derived class can have additional pointers at the end for virtual functions it added.

Perhaps a bit long winded, but if you are a C programmer new to C++ but use to using function pointers it helps to understand exactly what virtual functions are actually doing. Under the vast majority of circumstances they implement the function pointers for you. Virtual functions are often poorly understood and misused. If you wouldn''t otherwise need a function pointer then you don''t need a polymorphic class. From a C++ perspective if you are not calling functions in derived classes through pointers base classes you do not need the virtual keyword. Since you are dealing with a pointer to start with it is rare for the compiler to be able to identify that there is no polymorphism and skip the lookup. So most often you are adding overhead by using the virtual keyword when it is unneeded. That people misuse it so much make it hard to see that it is specifically for the situations where you would otherwise need a function pointer. You wouldn''t use a function pointer when there is only one possible function to call, rather you use it for a class of functions all taking the same parameter. When people use virtual with only one possible function to be called it makes you think it must be doing something else. It isn''t.
Keys to success: Ability, ambition and opportunity.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.