为什么要在C++;? 许多C++书籍和教程解释了如何做到这一点,但我没有看到一个令人信服的理由来选择这样做。p>

为什么要在C++;? 许多C++书籍和教程解释了如何做到这一点,但我没有看到一个令人信服的理由来选择这样做。p>,c++,function-pointers,C++,Function Pointers,我非常理解为什么C中需要函数指针(例如,在使用某些POSIX工具时)。但是,由于“this”参数,您不能向他们发送成员函数。但是,如果您已经在使用类和对象,为什么不使用面向对象的解决方案,比如函子呢 如果您能在真实世界中使用这样的函数指针,我们将不胜感激 更新:我感谢大家的回答。不过,我不得不说,这些例子都不能让我相信,从纯面向对象的角度来看,这是一种有效的机制 这就像使用lambdas一样。您总是可以将所有必要的局部变量传递给一个简单函数,但有时您必须传递多个局部变量 因此,使用成员函数可以避

我非常理解为什么C中需要函数指针(例如,在使用某些POSIX工具时)。但是,由于“this”参数,您不能向他们发送成员函数。但是,如果您已经在使用类和对象,为什么不使用面向对象的解决方案,比如函子呢

如果您能在真实世界中使用这样的函数指针,我们将不胜感激


更新:我感谢大家的回答。不过,我不得不说,这些例子都不能让我相信,从纯面向对象的角度来看,这是一种有效的机制

这就像使用lambdas一样。您总是可以将所有必要的局部变量传递给一个简单函数,但有时您必须传递多个局部变量


因此,使用成员函数可以避免将所有必需的成员字段传递给函子。就这些

> P>函子不是先验的面向对象(C++),术语“函子”通常指结构定义为<代码>运算符()/>代码,具有任意参数和返回值,可以用作替换实际函数或函数指针的语法降值。然而,他们的面向对象问题有很多问题,首先是可用性。这只是一大堆复杂的样板代码。为了像大多数对话框架一样获得一个像样的信令框架,需要大量的继承混乱

实例绑定的函数指针在这里非常有用(.NET用委托充分说明了这一点)

<>但是,C++成员函数指针仍然满足另一个需要。例如,假设您在一个列表中有很多值,您希望执行其中一个方法,比如它的
print()
。指向
YourType::size
的函数指针在这里很有用,因为它可以让您编写这样的代码:

std::for_each(lst.begin(), lst.end(), std::mem_fun(&YourType::print))

这是一个典型的场景。我们有一个通知框架,其中一个类可以注册到多个不同的通知。注册到通知时,我们传递成员函数指针。这实际上与C#事件非常相似


您特别询问了成员函数,但函数指针还有其他用途。在C++中,我需要使用函数指针的最常见的原因是当我想使用DeloLabyAuthor()加载DLL AR运行时。显然,这是在Windows中。在以可选DLL形式使用插件的应用程序中,动态链接不能在应用程序启动时使用,因为DLL通常不存在,而使用delayload是一种痛苦


加载库后,必须获得指向要使用的函数的指针。

过去,成员函数指针在以下情况下非常有用:

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());
    }
};
public:
    void SomeClass::DummyCallback( void* pRefCon ) [ static ]
    {
        reinterpret_cast<SomeClassT*>(pRefCon)->Callback();
    }
private:
    void class SomeClass::Callback() [ static ]
    {
        // some code ...
    }
类图像{
//避免重复循环代码
每个无效(无效(图像::*回调)(点)){
对于(int x=0;x
我已经在一个商业绘画应用程序中看到了这一点。(有趣的是,这是少数几个用预处理器更好地解决的C++问题之一)。
然而,今天,成员函数指针的唯一用途是在
boost::bind

的实现中。我在一个场景中使用了一个指向成员函数的函数指针,在这个场景中,我必须向某个第三方API对象提供一个带有预定义参数列表的回调函数指针(因此我无法传递任意参数)

我无法在全局名称空间中实现回调,因为它应该根据使用触发回调的第三方API的对象的状态来处理传入事件

所以我希望回调的实现是使用第三方对象的类的一部分。我所做的是,我在我想要实现回调的类中声明了一个公共和静态成员函数,并将指向它的指针传递给API对象(关键字
static
避免了
this
指针问题)

然后,我的对象的
这个
指针将作为回调的Refcon的一部分传递(幸运的是它包含了一个通用的
void*
)。 然后,虚拟的实现使用传递的指针调用类=)中包含的回调的实际的私有实现

它看起来像这样:

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());
    }
};
public:
    void SomeClass::DummyCallback( void* pRefCon ) [ static ]
    {
        reinterpret_cast<SomeClassT*>(pRefCon)->Callback();
    }
private:
    void class SomeClass::Callback() [ static ]
    {
        // some code ...
    }
公共:
void SomeClass::DummyCallback(void*pRefCon)[静态]
{
重新解释强制转换(pRefCon)->Callback();
}
私人:
void类SomeClass::Callback()[静态]
{
//一些代码。。。
}

我现在正在编写一些代码,用于实现状态机。解引用成员函数实现状态,但由于它们都在类中,因此它们可以共享一定数量的数据,这些数据对于整个状态机来说是全局的。使用普通(非成员)函数指针很难做到这一点


不过,我还不确定这是否是实现状态机的好方法。

我使用了成员函数指针解析文件。根据文件中找到的特定字符串,在映射中找到相同的值,并调用相关函数。这不是比较字符串的大型if..else if..else语句。

成员p最重要的一个用法
class functor1
{
public:
    functor1( Processor& o, int v ) : o_(o), v_(v) {}
    void operator()() {
        o_.operation( v_ ); // [1]
    }
private:
    Processor& o_;
    int v_;
};
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;
};
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();
}