簡體   English   中英

C++:成員數組 function 指向不同函數的指針

[英]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.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()) {}

您正在尋找的是指向成員函數的指針 這是一個簡短的示例,顯示了它們的聲明和用法:

#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(); }}} {}
};

試試 godbolt 編譯器資源管理器

這是一個更完整的示例,展示了如何處理這些。


體系結構注釋:小心指向非靜態成員函數的指針。 如果您的A實例被銷毀,但您仍然擁有成員 function 的 function 句柄,會發生什么情況? 是的,地獄凍結了:這個方法不再屬於 object,所以結果是災難性的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM