我有一个班级
class A{
A(/*constructor arguments*/);
double MethA(double);
};
我想在一个带有指向函数的指针的函数中传递方法MethA
:
double function(double (*f)(double), double x){
return f(x);
}
所以我正在做的是打电话
A a(/*constructor arguments*/);
function(a.MethA,1.0);
但它没有编译。
我很确定这个问题在其他地方得到了解答,但我无法找到,因为我不确定我使用的术语是否正确。我是否尝试将类方法上的指针作为函数参数传递?或者,将函数指针作为类的成员传递...我很困惑: - (
答案 0 :(得分:2)
当你需要使用指向成员函数的指针时,你需要传递两个不同的东西:
在C ++中,您不能将它们组合在一个结构中,就像您想要的那样:
A a;
bar(a.foo);
无效C ++。
相反,你必须这样做:
A a;
bar(a, &A::foo)
并相应地声明并实现bar():
void bar(A &a, void (A::*method)()) {
a.*method();
}
答案 1 :(得分:1)
如果您想了解如何正确使用成员函数指针,请参阅Arkadiy's答案。
<强> BUT 强>
根据评论中的要求:如果您使用的编译器支持lambdas(有些没有完整的C ++ 11)。您可以执行以下操作,它看起来更像您尝试使用的语法。
您对function
的定义更改为:
template <typename F>
double function(F f, double x){
return f(x);
};
一个函数模板,它接受一个可用double
调用的参数。
在您的通话现场,您可以这样做:
A a(/*constructor arguments*/);
function([&](double x){return a.MethA(x);},1.0);
通过引用生成一个就地绑定到类实例a
的函数对象。
模板可以在<type_traits>
中使用一些魔法制作完全类型安全,但是如果你传递了一些非常错误的话,它会给你模板喷射。
答案 2 :(得分:0)
它必须是静态函数!
#include <iostream>
#include <cassert>
class A {
public:
static double MethA(double x) { return 5 * x; }
};
typedef double (*ftype)(double);
double function(ftype f) {
assert(f != NULL);
return f(7);
}
int main(int, char**) {
// expect "35\n" on stdout
std::cout << function(A::MethA) << "\n";
}
它必须是静态的,因为在不知道你引用的是哪个A对象的情况下,你无法访问任何A的变量!如果需要A的非静态成员变量,则需要将对a的引用传递给静态函数:
#include <iostream>
#include <cassert>
class A {
double fX;
public:
A(double x) : fX(x) { }
double methB(double x) const { return fX * x; }
static double MethB(double x, const A& a) {
return a.methB(x);
}
};
typedef double (*ftype2)(double, const A&);
double function_with_context(ftype2 f, const A& a) {
assert(f != NULL);
return f(7, a);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function_with_context(A::MethB, a) << "\n";
}
但有时候使用继承和多态来实现这种接口会更好:
#include <iostream>
class MyInterface {
public:
virtual double f(double x) const = 0;
};
class A : public MyInterface {
double fX;
public:
A(double x) : fX(x) { }
double f(double x) const {
return fX * x;
}
};
double function(const MyInterface& o) {
return o.f(7);
}
int main(int, char**) {
A a(6);
// expect "42\n" on stdout
std::cout << function(a) << "\n";
}