我需要在另一个类中使用一个类中定义的函数。我没有重写整个函数,而是尝试将函数作为指针传递,如下所示:
class C {
public:
int get(int x) { return x*x; }
};
struct S {
int (*func) (int x);
};
int main() {
C c;
S s;
cout << c.get(3) << endl;
s.func = &C::get;
cout << s.func(3) << endl;
return 0;
}
这不起作用并出现以下错误:
func_ptr.cpp: In function ‘int main()’:
func_ptr.cpp:42:18: error: cannot convert ‘int (C::*)(int)’ to ‘int (*)(int)’ in assignment
是否可以做这样的事情,如果是这样,我该如何解决?而且,如果可能的话,我可以使用来自对象实例而不是类的指针吗?也就是说,可能使用在特定类实例中定义的变量。感谢。
答案 0 :(得分:5)
C::get()
是一个非静态成员函数,这意味着必须在C
的实例上调用它。它有一个隐含的第一个参数,this
指针,在调用函数时必须传递给它。
由于您的C::get()
似乎无需访问C
的任何数据成员,因此您可以将其设为static
成员函数。
static int get(int x) { return x*x; }
现在您的代码将按原样运行。
另一种选择是更改func
,使其成为C
成员函数的指针
struct S {
int (C::*func) (int x);
};
并将其作为
调用s.func = &C::get;
std::cout << (c.*(s.func))(3) << std::endl;
另一种选择是将S::func
的类型更改为std::function<int(int)>
。现在它可以保存任何可调用的(函数指针,函子,lambda),它将一个int
作为参数,并返回int
。
struct S {
std::function<int(int)> func;
};
s.func = std::bind(&C::get, &c, std::placeholders::_1);
std::cout << s.func(3) << std::endl;
答案 1 :(得分:1)
常规函数和成员函数有点不同。要使用成员函数,您需要一个对象来调用它(即成员函数体中的this指针)。
看一下std :: function和std :: bind,它们用于以统一的方式处理类似(可调用)实体的函数。他们可以管理全局函数,静态成员函数,lambdas,常规成员函数,仿函数,以及可以像函数一样调用的任何函数。
e.g:
struct S
{
std::function<int(int)> func;
};
C c;
S s;
s.func = std::bind( &C::get, &c, std::placeholders::_1 );
答案 2 :(得分:1)
如果你可以使用STL,那么你可以利用std :: function来保存一个指向函数的指针,std :: bind将特定指针绑定到一个特定的函数。它使您的代码看起来更清洁。 std :: bind查找静态和非静态成员函数。对于非静态成员函数,需要传递对象引用,以便它能够指向正确的地址。
以下是展示如何使用它的代码段:
std::bind(ClassName::MemberFunctionName, object, std::placeholders::_1)
std :: placeholders :: _ 1表示:: MemberFunctionName接受一个参数。