2009-01-27 33 views
6

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

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 
    } 
}; 

当我尝试编译这段代码,我得到的错误是

error: no matching function for call to 'Derived::Derived(string (MainClass::*)(int))'

其次

note: candidates are: Derived::Derived(string (*)(int))

任何想法,我可能做错了吗?

回答

8

您的语法对于C风格函数指针是正确的。它改成这样:

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

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

记得打电话strFunction,您将需要一个MainClass对象的实例。我经常发现使用typedefs很有用。

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

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

以及如果这些类是分离的并且您不能指定'MainClass :: * funPtr'? – fduff 2012-08-13 11:57:32

+0

然后我会推荐使用一个通用库,例如​​将参数设置为`boost :: function `并将函数传递给`boost :: bind` – 2012-08-13 12:46:15

0

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

2

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

你试图传递一个方法指针到一个构造函数,该函数需要一个函数指针。哪个不行。

+0

这很有道理。 – Chris 2009-01-28 19:06:16

4

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

4

您试图将指针传递到类MainClass的成员函数,但该函数需要一个指向一个普通的,即非成员函数。一个好的总结是here

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

0

由于编译器警告指出,成员函数指针与常规函数指针完全不同。

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) {}; 
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函数基本上把成员函数绑定到一个特定的对象。它负责编译器插入的这个指针。