我有一个类A,其中包含成员函数foo()和bar(),它们都返回指向类B的指针。如何在类A中声明包含函数foo和bar的数组作为成员变量?如何通过该数组调用这些函数?
成员函数指针的语法是 ReturnType (Class::*)(ParameterTypes...)
,例如:
typedef B* (A::*MemFuncPtr)(); // readability
MemFuncPtr mfs[] = { &A::foo, &A::bar }; // declaring and initializing the array
B* bptr1 = (pointerToA->*mfs[0])(); // call A::foo() through pointer to A
B* bptr2 = (instanceOfA.*mfs[0])(); // call A::foo() through instance of A
查看例如这篇InformIT文章,了解有关成员指针的更多详细信息。
您可能还想了解Boost.Bind和Boost.Function(或其TR1等效物),它们允许您将成员函数指针不透明地绑定到实例:
typedef boost::function<B* ()> BoundMemFunc;
A instanceOfA;
BoundMemFunc mfs[] = {
boost::bind(&A::foo, &instanceOfA),
boost::bind(&A::bar, &instanceOfA)
};
B* bptr = mfs[0](); // call A::foo() on instanceOfA
如果要将这样的数组用作成员变量,请注意您无法使用成员初始化器列表来初始化数组。因此,您只能在构造函数体中对其进行赋值:
A::A {
mfs[0] = &A::foo;
}
如果可能的话,使用可以在该位置进行初始化的类型,例如std::vector
或boost::array
,否则请重新考虑代码逻辑。
struct A {
const std::vector<MemFuncPtr> mfs;
// ...
};
namespace {
std::vector<MemFuncPtr> init_mfs() {
std::vector<MemFuncPtr> mfs;
mfs.push_back(&A::foo);
mfs.push_back(&A::bar);
return mfs;
}
}
A::A() : mfs(init_mfs()) {}
#include <iostream>
class B {
public:
B(int foo): foo_(foo) {
std::cout << "Making a B with foo_ = " << foo_ << std::endl;
}
~B(void) {
std::cout << "Deleting a B with foo_ = " << foo_ << std::endl;
}
int foo_;
};
class A {
public:
A(void) {
funcs_[0] = &A::foo;
funcs_[1] = &A::bar;
}
B* foo(void) {
return new B(3);
}
B* bar(void) {
return new B(5);
}
// Typedef for the member function pointer, for everyone's sanity.
typedef B* (A::*BMemFun)(void);
BMemFun funcs_[2];
};
int main(int argc, char *argv[]) {
A a;
for (int i = 0; i < 2; ++i) {
A::BMemFun func = a.funcs_[i];
// Call through the member function pointer (the .* operator).
B* b = (a.*func)();
delete b;
}
return 0;
}
我在C++ FAQ中关于成员函数指针的部分找到了这些信息。
#include <vector>
class B;
class A {
public:
B* foo() {
// return something;
return nullptr;
}
B* bar() {
// return something;
return nullptr;
}
//C++ 11: functional brings std::function, which has zero overhead
//but is actually a useful type with which one can work
std::vector<std::function<B*()>> container;
/* [=]() { return foo(); }
* that's a lambda. In practice it "compiles away", i.e. calling
* the lambda function is the same as calling foo or bar directly
* Note how [=] means we're passing in "this", so that we can
* actually call foo().
*/
A() : container{{[=]() { return foo(); }}, {[=]() { return bar(); }}} {}
};
这里有一个更完整的示例,展示了如何使用它们。
A
实例被销毁了,但你仍然持有一个成员函数的函数句柄会发生什么?没错,地狱会冻结:再也没有对象拥有这个方法,结果将是灾难性的。