将类成员函数作为参数传递给全局函数

时间:2014-03-28 14:20:51

标签: c++ function-pointers member-function-pointers member-functions

我试图将A类的成员函数作为参数传递给全局函数。我该怎么做才能做到这一点?这也是个好主意吗?上下文:我想这样做是因为(同义词)doSomething(...)是一个非常通用的函数,在main()以及不同的类中使用。因此,我可以避免在我的项目中拥有相同代码的多个副本。什么是替代品(如果它不是最佳的)?

#include <iostream>
using namespace std;

double doSomething(int i, double (*f)(double)) { return (*f)(i); }

class A{
public:
    A(double x) : number(x) {}
    double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a member function as parameter
    double multiply(double i) {return number*i;}
private:
    double number;
};

int main() {

    A obj(5.0);
    cout << obj.times(3.5) <<endl;

    return 0;
}

编译抱怨:

../src/test5.cpp: In member function ‘double A::times(double)’:
../src/test5.cpp:17:63: error: cannot convert ‘double (A::*)(double)’ to ‘double (*)(double)’ for argument ‘2’ to ‘double doSomething(int, double (*)(double))’
  double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a parameter member function as parameter
                                                               ^
../src/test5.cpp:17:65: warning: control reaches end of non-void function [-Wreturn-type]
  double times(double i) { return ::doSomething(i, &A::multiply);} //calles the global function and gives a parameter member function as parameter

3 个答案:

答案 0 :(得分:1)

您的doSomething函数需要一个自由函数指针(自由函数表示非成员函数)。您尝试将成员函数指针传递给它。这不行。为什么?如果您有免费功能,请说void f(double),您只需拨打电话:

f(3.14);

另一方面,当你有一个成员(和非静态)函数时,要调用它你需要一个对象,例如:

obj.m(3.14);

并且您无法在没有对象的情况下调用成员函数。因此,成员函数不能与自由函数互换使用,因为它们以不同的方式被调用。考虑(*f)(i)函数中的doSomething调用 - A调用multiply对象的内容是什么?

您的设计需要重新思考。如果你想共享代码,也许你需要一些类层次结构和基类中的公共代码?

答案 1 :(得分:1)

使用C ++ 11,您可以这样做:

#include <functional>

typedef std::function<double (double)> do_something_function;
double doSomething(double i, do_something_function f) { return f(i); }

class A{
    public:
    A(double x) : number(x) {}
    double times(double i) {
        do_something_function f = [this] (double i) {
            return this->multiply(i);
        };
        return ::doSomething(i, f);
    }
    double multiply(double i) {
        return number * i;
    }

    private:
    double number;
};

答案 2 :(得分:0)

通过指针调用类的non-static函数成员的方式与在独立函数上执行它的方式不同,因为需要指向实例的指针

#include <iostream>
using namespace std;

class A;
typedef double (A::*f)(double);
double doSomething(double i, f p, A* ap);

class A {
public:

    A(double x) : number(x) {
    }

    double times(double i) {
        return ::doSomething(i, &A::multiply, this);
    } //calles the global function and gives a member function and pointer to A

    double multiply(double i) {
        return number*i;
    }
private:
    double number;
};

double doSomething(double i, double (A::*fp)(double), A* ap) {
    return (ap->*fp)(i);  // call *fp on *ap
}

int main() {

    A obj(5.0);
    cout << obj.times(3.5) << endl;

    return 0;
}

example