[英]C++: Array of member function pointers to different functions
我有一個 class A,其中包含成員函數 foo() 和 bar(),它們都返回一個指向 class B 的指針。如何將包含函數 foo 和 bar 的數組聲明為 class A 中的成員變量? 以及如何通過數組調用函數?
成員函數指針語法是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部分是我找到所有這些信息的地方。
C++ 並不古老(閱讀:C++11 及更高版本)使這一切變得更容易。 在現代 C++,你可以做
#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
實例被銷毀,但您仍然擁有成員 function 的 function 句柄,會發生什么情況? 是的,地獄凍結了:這個方法不再屬於 object,所以結果是災難性的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.