无法在类之间传递指向函数的指针

时间:2009-01-27 19:05:03

标签: c++

我正在尝试将指向一个类中定义的函数的指针传递给另一个类。经过大量研究,我相信我的语法是正确的,但我仍然遇到编译器错误。以下是一些演示我的问题的代码:

class Base
{
public:
    BaseClass();
    virtual ~BaseClass();
};

class Derived : public Base
{
public:
    // assign strFunction to the function pointer passed in
    Derived(string (*funPtr)(int)) : strFunction(funPtr);
    ~Derived();

private:
    // pointer to the function that is passed in
    string (*strFunction)(int value);
};

class MainClass
{
public:
    MainClass()
    {
        // allocate a new Derived class and pass it a pointer to myFunction
        Base* myClass = new Derived(&MainClass::myFunction);    
    }

    string myFunction(int value)
    {
        // return a string
    }
};

当我尝试编译此代码时,我得到的错误是

  

错误:没有匹配函数来调用'Derived :: Derived(string(MainClass :: *)(int))'

接着是

  

注意:候选者是:Derived :: Derived(string(*)(int))

知道我可能做错了吗?

9 个答案:

答案 0 :(得分:8)

您的语法对于C样式函数指针是正确的。将其更改为:

Derived(string (MainClass::*funPtr)(int)) : strFunction(funPtr) {}

string (MainClass::*strFunction)(int value);

记得调用strFunction,你需要一个MainClass对象的实例。我经常觉得使用typedef很有用。

typedef string (MainClass::*func_t)(int);
func_t strFunction;

Derived(func_t funPtr) : strFunction(funPtr) {}

答案 1 :(得分:5)

您可以详细了解C++ member function pointer syntax here的严重邪恶。

答案 2 :(得分:4)

是的,&MainClass::myFunction的类型是指向成员的类型,而string(*)(int)是指向函数的指针类型。它们不兼容,因为您必须使用引用或指向类实例的指针并使用。*或 - > *运算符来使用指向成员的指针,而指向函数的指针不会附加到类和可以直接调用。

答案 3 :(得分:4)

您正在尝试将指针传递给类MainClass的成员函数,但该函数需要指向普通(即非成员)函数的指针。一个很好的总结是here

区别很重要,因为成员函数有一个隐藏的额外参数,它告诉函数将“this”指针应用于哪个函数。所以指针类型不可互换。

答案 4 :(得分:2)

函数指针(指向未绑定函数的指针)和指向方法的指针(指向绑定到类定义的非静态函数的指针)在c++中是不同的。这是因为非静态方法具有隐式this参数,要求始终在其类的实例的上下文中调用它们。

您正在尝试将方法指针传递给带有函数指针的构造函数。哪个不行。

答案 5 :(得分:2)

另一个语法问题:


    // assign strFunction to the function pointer passed in
    Derived(string (*funPtr)(int)) : strFunction(funPtr);

替换为:


    // assign strFunction to the function pointer passed in
    Derived(string (*funPtr)(int)) : strFunction(funPtr) {};

答案 6 :(得分:1)

您可能希望使用与此(未经测试)代码类似的std::tr1::bindstd::tr1::function

class Derived: public Base
{
  public:
    typedef std::tr1::function<string(int)> StringFunc;

    Derived(StringFunc);

  ...

  private:
    StringFunc strFunction;
}

并在MainClass构造函数中:

myBase = new Derived(std::tr1::bind(&MainClass::myFunction, *this, _1);

bind函数基本上将成员函数绑定到特定对象。它负责编译器插入的this指针。

答案 7 :(得分:0)

对象方法有一个隐藏的“this”参数。如果将方法传递给另一个类,那么什么会填充到“this”参数中?您可以使用静态(类)方法来完成它。

答案 8 :(得分:0)

正如编译器警告所示,成员函数指针与常规函数指针完全不同。