类变量中类方法的列表/向量

时间:2015-10-14 22:25:50

标签: c++ class vector function-pointers class-method

我需要维护一个方法列表,这些方法将以不同的顺序执行以进行测试。我们正在从C转向C ++以使用谷歌框架。是否有可能维护一些函数指针,这些函数指向一些用于在类中执行的类方法,以便它们可以在实例化后使用?请参阅http://cpp.sh/265y

#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef void (*funcType)();

class Sample {
    public:
    vector<funcType> func_list;

    Sample();

    void formList();
    void method1();
    void method2();
    void method3();    
};

void Sample::formList() {
    func_list.push_back(&method1);
    func_list.push_back(&method2);
    func_list.push_back(&method3);
}

void Sample::method1 () {
    cout << "method1" << endl;
}

void Sample::method2 () {
    cout << "method2" << endl;
}

void Sample::method3 () {
    cout << "method3" << endl;
}

int main()
{
    Sample sample; //* = new Sample();
    sample.formList();
    vector<funcType>::iterator it;
    for (it = sample.func_list.begin(); it != sample.func_list.end(); ++it) {
         ((*it));
    }

}

答案:http://cpp.sh/8rr2

2 个答案:

答案 0 :(得分:2)

简介

您当前已将funcType声明为void(*)()的别名,它是指向某个函数的指针,该函数不接受任何参数并返回void。您应该使用的是指向成员函数的指针,因为这将适合您尝试调用的实体。

class Sample;
typedef void (Sample::*funcType)(); 

当您要取得他们的地址时,您还必须限定您的会员功能:

void Sample::formList() {
    func_list.push_back(&Sample::method1);
    func_list.push_back(&Sample::method2);
    func_list.push_back(&Sample::method3);
}

当调用一个成员函数时,你需要一个你想要调用它的对象,这意味着你 - 为了调用一个成员函数,通过ha 指向成员函数 - 必须在呼叫站点提供一个对象。

for (it = sample.func_list.begin(); it != sample.func_list.end(); ++it) {
     (sample.*(*it)) (); // invoke the member-function referred to by `it`
}                        // on the object named `sample`

进一步阅读

示例实施

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Sample;
typedef void (Sample::*funcType)();

class Sample {
  public:
    vector<funcType> func_list;

    void formList();
    void method1();
    void method2();
    void method3();    
};

void Sample::formList() {
  func_list.push_back(&Sample::method1);
  func_list.push_back(&Sample::method2);
  func_list.push_back(&Sample::method3);
}

void Sample::method1 () {
  cout << "method1" << endl;
}

void Sample::method2 () {
  cout << "method2" << endl;
}

void Sample::method3 () {
  cout << "method3" << endl;
}

int main()
{
  Sample sample; //* = new Sample();
  sample.formList();
  vector<funcType>::iterator it;
  for (it = sample.func_list.begin(); it != sample.func_list.end(); ++it) {
    (sample.*(*it)) ();
  }
}
method1
method2
method3

答案 1 :(得分:2)

您可以使用可怕的指针指向成员函数语法:

<强> Live On Coliru

// Example program
#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Sample;

typedef void (Sample::*funcType)();

class Sample {
  public:
    vector<funcType> func_list;

    Sample(){}

    void formList();
    void method1();
    void method2();
    void method3();
};

void Sample::formList() {
    func_list.push_back(&Sample::method1);
    func_list.push_back(&Sample::method2);
    func_list.push_back(&Sample::method3);
}

void Sample::method1() { cout << "method1" << endl; }

void Sample::method2() { cout << "method2" << endl; }

void Sample::method3() { cout << "method3" << endl; }

int main() {
    Sample sample; //* = new Sample();
    sample.formList();
    vector<funcType>::iterator it;
    for (it = sample.func_list.begin(); it != sample.func_list.end(); ++it) {
        (sample.*(*it))(); // HORRIFIC, INNIT? SEE BELOW FOR BETTER
    }
}

更好:

但是,使用C ++ 11 / TR1 std::function<>boost::function<>可以更加通用:

typedef function<void(Sample*)> funcType;

// ...
func_list.push_back(mem_fn(&Sample::method1));
func_list.push_back(mem_fn(&Sample::method2));
func_list.push_back(mem_fn(&Sample::method3));

同时查看 Live On Coliru

for (it = sample.func_list.begin(); it != sample.func_list.end(); ++it) {
    (*it)(&sample); // much better
}
  

增加的多功能性主要在于您可以满足不同的签名: Live On Coliru

class Sample {
  public:
    vector<funcType> func_list;

    Sample(){}

    void formList();
    void method1(int);
    void method2(std::string);
    void method3(double, double, double);
};

void Sample::formList() {
    using std::placeholders::_1;
    func_list.push_back(bind(&Sample::method1, _1, 42));
    func_list.push_back(bind(&Sample::method2, _1, "Hello world"));
    func_list.push_back(bind(&Sample::method3, _1, 1, 2, 3));
}