views:

799

answers:

9

A lot of C++ books and tutorials explain how to do this, but I haven't seen one that gives a convincing reason to choose to do this.

I understand very well why function pointers were necessary in C (e.g., when using some POSIX facilities). However, AFAIK you can't send them a member function because of the "this" parameter. But if you're already using classes and objects, why not just use an object oriented solution like functors?

Real world examples of where you had to use such function pointers would be appreciated.

Update: I appreciate everyone's answers. I have to say, though, that none of these examples really convinces me that this is a valid mechanism from a pure-OO perspective...

A: 

It is like using lambdas. You always can pass all necessary local variables to a simple function, but sometimes you have to pass more then one of them.

So using member functions will save you from passing all necessary member fields to a functor. That's all.

Mykola Golubyev
+11  A: 

Functors are not a priori object-oriented (in C++, the term “functor” usually means a struct defining an operator () with arbitrary arguments and return value that can be used as syntactical drop-in replacements to real functions or function pointers). However, their object-oriented problem has a lot of issues, first and foremost usability. It's just a whole lot of complicated boilerplate code. In order for a decent signalling framework as in most dialog frameworks, a whole lot of inheritance mess becomes necessary.

Instance-bound function pointers would be very beneficial here (.NET demonstrates this amply with delegates).

However, C++ member function pointers satisfy another need still. Imagine, for example, that you've got a lot of values in a list of which you want to execute one method, say its print(). A function pointer to YourType::size helps here because it lets you write such code:

std::for_each(lst.begin(), lst.end(), std::mem_fun(&YourType::print))
Konrad Rudolph
I never knew I can use member function pointers like this..and always wondered what is the use of them without the this pointer. I can save myself from writing unnecessary functors now
Naveen
of course the irony of your example is that std::mem_fun returns a functor that wraps the member function :-P. So you've given an example of a functor even still...
Evan Teran
That's a good answer, though I have to admit I still don't like this mechanism, it smells too "switchlike" for me.
Uri
+2  A: 

Here is a typical scenario we have here. We have a notification framework, where a class can register to multiple different notifications. When registering to a notification, we pass the member function pointer. This is actually very similar to C# events.

class MyClass
{
    MyClass()
    {
        NotificationMgr::Register( FunctionPtr( this, OnNotification ) );
    }
    ~MyClass()
    {
        NotificationMgr::UnRegister( FunctionPtr( this, OnNotification ) );
    }

    void OnNotification( ... )
    {
        // handle notification
    }
};
decasteljau
In Java the standard idiom is to have an interface for the notifiable items. Wouldn't an abstract class be a cleaner design in C++ as well?
Uri
When you have an interface, it may become complex to manage if the class is registering many notifications.The name of the callback is enforced by the Interface.If many interfaces have the same name, how do you manage that? In C#, and inside the example above, the class decide on the callback name.
decasteljau
A: 

You asked specifically about member functions, but there are other uses for function pointers as well. The most common reason why I need to use function pointers in C++ is when I want to load a DLL ar runtime using LoadLibrary(). This is in Windows, obviously. In applications that use plugins in the form of optional DLLs, dynamic linking can't be used at application startup since the DLL will often not be present, and using delayload is a pain.

After loading the library, you have to get a pointer to the functions you want to use.

John Dibling
+2  A: 

In the past, member function pointers used to be useful in scenarios like this:

class Image {
    // avoid duplicating the loop code
    void each(void(Image::* callback)(Point)) {
        for(int x = 0; x < w; x++)
            for(int y = 0; y < h; y++)
                callback(Point(x, y));
    }

    void applyGreyscale() { each(&Image::greyscalePixel); }
    void greyscalePixel(Point p) {
        Color c = pixels[p];
        pixels[p] = Color::fromHsv(0, 0, (c.r() + c.g() + c.b()) / 3);
    }

    void applyInvert() { each(&Image::invertPixel); }
    void invertPixel(Point p) {
        Color c = pixels[p];
        pixels[p] = Color::fromRgb(255 - c.r(), 255 - r.g(), 255 - r.b());
    }
};

I've seen that used in a commercial painting app. (interestingly, it's one of the few C++ problems better solved with the preprocessor).

Today, however, the only use for member function pointers is inside the implementation of boost::bind.

I wouldn't say that boost::bind is the only use. Member function pointers are often used to implement user-defined conversions to Boolean types. Their advantage as a Boolean type over "bool" is that they don't automatically promote to integers.
Nathan Kitchen
A: 

I used a function pointer to a member function in a scenario where I had to provide a function pointer to a callback with a predefined parameter list (so I couldn't pass arbitrary parameters) to some 3rd-party API object.

I could not implement the callback in the global namespace because it was supposed to handle incoming events based on state of the object which made use of the 3rd party API which had triggered the callback.

So I wanted the implementation of the callback to be part of the class which made use of the 3rd-party object. What I did is, I declared a public and static member function in the class I wanted to implement the callback in and passed a pointer to it to the API object (the static keyword sparing me the this pointer trouble).

The this pointer of my object would then be passed as part of the Refcon for the callback (which luckily contained a general purpose void*). The implementation of the dummy then used the passed pointer to invoke the actual, and private, implementation of the callback contained in the class = ).

It looked something like this:

public:
    void SomeClass::DummyCallback( void* pRefCon ) [ static ]
    {
        reinterpret_cast<SomeClassT*>(pRefCon)->Callback();
    }
private:
    void class SomeClass::Callback() [ static ]
    {
        // some code ...
    }
Bjoern
this is not an example of a member function pointer. But instead an example of passing a this pointer to a C style callback and calling an ordinary member function with the object. member function pointers have nothing to do with this.
Evan Teran
Although I wouldn't have been able to do what I described without the ability to use a function pointer to a (static) member function in C++, if I am correct? Sorry, If this has been off-topic, but I thought it a valid use for a function pointer to a member...
Bjoern
static members act entirely different from c++ member function's when it comes to a function pointer perspective. static's have no need for a "this" pointer (hence you could use them for that purpose). Though static's are not requires to have c style linkage...
Evan Teran
+2  A: 

I have some code I'm working on right now where I used them to implement a state machine. The dereferenced member functions implement the states, but since they are all in the class they get to share a certian amount of data that is global to the entire state machine. That would have been tough to accomplish with normal (non-member) function pointers.

I'm still undecided on if this is a good way to implement a state machine though.

T.E.D.
A: 

I have used member function pointers parsing a file. Depending on specific strings found in the file the same value was found in a map and the associated function called. This was instead of a large if..else if..else statement comparing strings.

A: 

The single most important use of member pointers is creating functors. The good news is that you hardly even need to use it directly, as it is already solved in libraries as boost::bind, but you do have to pass the pointers to those libs.

class Processor
{
public:
   void operation( int value );
   void another_operation( int value );
};
int main()
{
   Processor tc;
   boost::thread thr1( boost::bind( &Processor::operation, &tc, 100 ) );
   boost::thread thr2( boost::bind( &Processor::another_operation, &tc, 5 ) );
   thr1.join();
   thr2.join();
}

You can see the simplicity of creating a thread that executes a given operation on a given instance of a class.

The simple handmade approach to the problem above would be on the line of creating a functor yourself:

class functor1
{
public:
    functor1( Processor& o, int v ) : o_(o), v_(v) {}
    void operator()() {
        o_.operation( v_ ); // [1]
    }
private:
    Processor& o_;
    int v_;
};

and create a different one for each member function you wish to call. Note that the functor is exactly the same for operation and for *another_operation*, but the call in [1] would have to be replicated in both functors. Using a member function pointer you can write a simple functor:

class functor
{
public:
   functor( void (*Processor::member)(int), Processor& p, int value )
      : member_( member ), processor_(p), value_( value ) {}

   void operator()() {
      p.*member(value_);
   }
private:
   void (*Processor::member_)(int);
   Processor& processor_;
   int value;
};

and use it:

int main() {
   Processor p;
   boost::thread thr1( functor( &Processor::operation, p, 100 ) );
   boost::thread thr2( functor( &Processor::another_operation, p, 5 ) );
   thr1.join();
   thr2.join();
}

Then again, you don't need to even define that functor as boost::bind does it for you. The upcoming standard will have its own version of bind along the lines of boost's implementation.

David Rodríguez - dribeas