2010-08-25 111 views
6

我有一個包含成員函數foo()和bar()的類A,它們都返回一個指向類B的指針。我如何聲明一個包含函數foo和bar的數組作爲A類中的成員變量?我如何通過數組調用函數?C++:不同函數的成員函數指針數組

回答

17

成員函數指針語法是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 

參見例如this InformIT article瞭解更多關於成員指針的細節。

您可能還需要尋找到Boost.BindBoost.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::vectorboost::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()) {} 
+0

你也可以考慮使用std :: function。 – Puppy 2010-08-25 13:21:10

+0

@DeadMG:我提到了TR1版本,但是因爲具有最廣泛的可用性,所以選擇了Boost版本。我個人認爲C++ 0x版本不夠普及,新標準還沒有最終確定。 – 2010-08-25 13:34:35

+0

啊,所以你做到了。由於我自己得到了一個C++ 0x編譯器,我不習慣看到這些增強變體。 – Puppy 2010-08-25 14:04:29

2

你要找什麼因爲指向成員函數。下面是顯示了它們的聲明和使用很短的例子:

#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 section on pointers to member functions是,我發現所有這些信息。