【问题标题】:unable to pass a pointer to a function between classes无法在类之间传递指向函数的指针
【发布时间】:2012-08-13 20:46:38
【问题描述】:

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

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

知道我做错了什么吗?

【问题讨论】:

    标签: c++


    【解决方案1】:

    您的语法对于 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) {}
    

    【讨论】:

    • 如果类被解耦并且你不能指定'MainClass::*funPtr'怎么办?
    • 那么我建议使用通用库,例如​​将参数设为boost::function<std::string()> 并使用boost::bind 传递函数
    • tx 但是非升压项目呢? std::function()std::bind() 仅在我们没有的 C++11 中可用。
    • @fduff:它们实际上也可以在 tr1 中访问。如果这仍然不是一个选项,我建议您更新您的工具链,或者在 stackoverflow 上提出更详细的问题,并让某人提出更适合您的特定目标的答案。
    • 你说得对,这些功能是tr1的一部分,在vs2010下可用。我会仔细看看,tx。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          您正在尝试将方法指针传递给采用函数指针的构造函数。这是行不通的。

          【讨论】:

            【解决方案6】:

            另一个语法问题:

            
                // 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) {};
            

            【讨论】:

              【解决方案7】:

              您可能想研究使用类似于此(未经测试的)代码的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);
              

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

              【讨论】:

                【解决方案8】:

                对象方法有一个隐藏的“this”参数。如果将方法传递给另一个类,“this”参数中会填入什么?您也许可以使用静态(类)方法来做到这一点。

                【讨论】:

                  【解决方案9】:

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

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-04-07
                    • 1970-01-01
                    • 2015-08-05
                    • 2018-04-05
                    • 1970-01-01
                    • 1970-01-01
                    • 2017-01-19
                    相关资源
                    最近更新 更多