Skip to main content
gamedev.net
🔒 Locked

C++ member function pointers

Started by AshleysBrain 2 replies 600+ views
Original Post
AshleysBrain
AshleysBrain
Hi, I just read a couple of articles on member function pointers. Seems a pretty obfuscated corner of C++. Anyway, I'm trying to make an extension SDK for one of my projects, using DLLs. Ideally the developer should create a class to represent their object in the application. The application needs to end up calling member functions of this class (which I'll call UserClass). UserClass is derived from an abstract class, ExtensionClass, defining standard routines such as Draw(). UserClass returns to the application some member function pointers for various new routines specific to that UserClass implementation. All the routines take 1 standard parameter. The application knows that the extension is a derivative of ExtensionClass, but needs to call one of the specific routines, via one of the returned member function pointers. It also has the pointer to the UserClass, but because the type is not specifically known (it is defined only in the DLL), the pointer will have to be considered an ExtensionClass pointer. When the application calls the member function, will it work? I.e. ExtensionClassPtr->*UserClassMemberPtr(param); even though the user class function is not known by the application. I understand this is a very implementation specific problem. I'm on VC++ 6.0, and not worried about portability. The call should be fast and efficient, but not worried about dropping 3 or 4 cpu cycles per call. Or should I just forget it and use ordinary DLL exports? Would Fast Delegates as suggested by http://www.codeproject.com/cpp/FastDelegate.asp be a good idea? Or I also read about boost::function? What's the best way to tackle this? Thanks all
Construct (Free open-source game creator)
Oluseyi
Oluseyi
Use function objects.

class FunctionObject{public:  virutal FunctionObject() = 0;  virtual ~FunctionObject() {}  virtual void operator () () = 0;};class SomeClass{  // constructor, destructor, etcpublic:  FunctionObject * callback() { return myCallbackFunction; }private:  FunctionObject * myCallbackFunction;};class CallingCode{  // stuffpublic:  void doCallback(FunctionObject * callback) { *callback(); }  // stuff};// invocation exampleCallingCode c;SomeClass s;c.doCallback(s.callback());

FunctionObjects can be passed around with impunity because they are values from the owning class' perspective: their signatures are not modified by being class properties.
AshleysBrain
AshleysBrain
Sorry Oluseyi, I don't quite understand your example:

- What inherits and implements FunctionObject's pure virtual routines?
- Where is a member function pointer used?
Construct (Free open-source game creator)
Oluseyi
Oluseyi
Quote:
Original post by AshleysBrain
- What inherits and implements FunctionObject's pure virtual routines?

Any specific function object you want to write (I left it out of my example). Because of C++'s static typing system, you have to provide a fixed interface for runtime polymorphic dispatch, which is why we have the abstract base class FunctionObject in the first place.

(Of course, if C++ had dynamic typing, it probably would have first-class function objects, anyway, but that's an unrelated discussion.)

Quote:
- Where is a member function pointer used?

It isn't, which is the whole point. Pass around function objects instead of member function pointers and all the problems with signature mismatches (because the class is now part of the member function signature) disappear. You will need to jump through a few more hoops when it comes to class data member access - you may have to define a certain FunctionObject-derived class within your data class, or declare it a friend - but it simplifies more problems than it causes.

class SomeOtherClass{  // stuffpublic:  FunctionObject * callback() { return myFunctionObject; }  struct SomeFunction : FunctionObject  {    SomeFunction(int someData) : data(someData);    void operator () () {}    bool operator () (int n) { return n < data; }  private:    int data;  };  SomeFunction * myCallbackObject;};


That should give you a better idea of the possibilities using this technique. It is not intended to be an exhaustive illustration; I expect you to go read up on function objects and see how they fit into your design on your own.

Topic Locked

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

Sign in to reply to this topic.