Why would one use function pointers to member meth

2020-06-05 01:22发布

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...

10条回答
Rolldiameter
2楼-- · 2020-06-05 02:01

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.

查看更多
一夜七次
3楼-- · 2020-06-05 02:01

A pointer to a member function is object-agnostic. You need it if you want to refer to a function by value at run-time (or as a template parameter). It comes into its own when you don't have a single object in mind upon which to call it.

So if you know the function, but don't know the object AND you wish to pass this knowledge by value, then point-to-member-function is the only prescribed solution. Iraimbilanja's example illustrates this well. It may help you to see my example use of a member variable. The principle is the same.

查看更多
太酷不给撩
4楼-- · 2020-06-05 02:05

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 ...
    }
查看更多
乱世女痞
5楼-- · 2020-06-05 02:14

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))
查看更多
登录 后发表回答