3

I'm writing a delegate class for educational purposes and have run into a little problem. The delegate must be able to call not only functions but also member methods of objects, which means that I need to store a pointer to a method:

void (classname::*methodPtr)(...);

And I need to store pointers to methods from different classes and with different argument lists. At first I just wanted to cast the method pointer to void *, but the compiler dies with an invalid cast error. Turns out that sizeof(methodPtr) == 8 (32-bit system here), but casts to unsigned long long also fail (same compiler error - invalid cast). How do I store the method pointer universally then?

I know it's not safe - I have other safety mechanisms, please just concentrate on my question.

IneQuation
  • 1,244
  • 11
  • 27

2 Answers2

4

You don't. You use run-time inheritance, if you need abstraction, and create a derived class which is templated on the necessities, or preferably, just create a plain old functor via the use of a function. Check out boost::bind and boost::function (both in the Standard for C++0x) as to how it should be done- if you can read them past all the macro mess, anyway.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • OK, let me check if I understand you correctly - you suggest that I should create a base class for the delegate with a virtual operator() and then derive from it a templated one? And by a functor do you mean a templated function that calls the method accordingly? I used this solution initially, but it has two downsides - the compiler needs to know everything at compile time, so only static objects are supported, and there is one instance of the templated function created per every object. – IneQuation Jun 10 '11 at 15:54
  • @IneQuation: Yes. I don't know what you mean by only static objects- any object in C++ which supports the correct signature via `operator()` can be used, and there are no objects for which it's unknown. – Puppy Jun 10 '11 at 16:55
1

You better listen to DeadMG. The problem is, that the size of a member pointer depends on the class type for which you want to form the member pointer. This is so, because depending on the kind of class layout (for example if the class have virtual bases and so on) the member pointer has to contain various offset adjustment values - there is no "one size fits all" member pointer type you can count on. It also means, that you can not assume to have a "castable" integral type which can hold every possible member function pointer.

Nordic Mainframe
  • 28,058
  • 10
  • 66
  • 83