这个问题在这里已有答案:
A有很多B类,A类有一个对象b。这个对象b有一个函数(calc)需要一个指向A对象中方法的指针。这个方法(好玩)在类中访问私有变量(在我的例子中只返回3)。
class A;
class B {
public:
virtual int calc ( int (A::*fun)()) { return 2*fun(); };
};
class A {
B* b;
public:
A (B* b_) : b (b_) {};
int fun() { return 3; };
int run(){ return b->calc(&A::fun); };
};
int main() {
B* b = new B();
A a(b);
a.run();
return 0;
}
如何在B类中定义calc
方法时正确使用指向方法的指针?
我收到此错误消息:
teste.cpp:10:58: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘fun (...)’, e.g. ‘(... ->* fun) (...)’
virtual int calc ( int (A::*fun)()) { return 2*fun(); };
^
如果对你来说可行,我推荐使用std::function
方法。但是,为了完整起见,以下是如何正确使用指针到成员函数的方法。
指向成员的指针本身不存储A
的“当前”实例,因此您需要明确地传递它。然后使用特殊的->*
(或.*
)语法来调用它。
virtual int calc (A* value, int (A::*fun)()) {
return 2 * (value->*fun)();
};
然后你会称之为b->calc(this, &A::fun);
。
您可以按照自己的方式执行此操作,但成员函数必须是特定实例上的called:
class A;
class B {
public:
virtual int calc(A* a, int (A::*fun)()) { return 2 * (a->*fun)(); };
};
class A {
B* b;
public:
A(B* b_) : b(b_) {};
int fun() { return 3; };
int run() { return b->calc(this, &A::fun); }; // now also passing this pointer
};
int main() {
B* b = new B();
A a(b);
a.run();
return 0;
}
如果你可以在没有calc()
虚拟的情况下生活,那么lambda也是一个选择:
class A;
class B {
public:
template<typename T>
int calc(T fun) { return 2 * fun(); };
};
class A {
B* b;
public:
A(B* b_) : b(b_) {};
int fun() { return 3; };
int run() {
return b->calc([this]() {return fun(); } );
};
};
int main() {
B* b = new B();
A a(b);
a.run();
return 0;
}
定义指针类方法并将其初始化为(假设SomeFn与签名匹配):
RetType (ClassName::*pfn)(Args) = &ClassName::SomeFn;
被称为:
ClassName * ptr = GetClassPtr();
(ptr->*pfn)(arg, arg);
如果你能够使用C ++ 11,那么你应该使用std::function和std::bind:否则你需要使用pointer to member function +指向实例的指针。
用C ++ 11
#include <functional>
class B {
public:
virtual int calc (std::function<int()>&& fun) { return 2 * fun(); }; };
};
class A {
B* b;
public:
A (B* b_) : b (b_) {};
int fun() { return 3; };
int run() { return b->calc(std::bind(&A::fun, this)); };
};
没有C ++ 11
class B {
public:
virtual int calc (int(A::*fnptr)(), A* a) { return 2 * (a->*fnptr)(); };
};
class A {
B* b;
public:
A (B* b_) : b (b_) {};
int fun() { return 3; };
int run() { return b->calc(&A::fun, this); };
};
参见示例here。