Мне нужно вести список методов, которые будут выполняться в разных порядках для тестирования. Мы переходим от C к C ++, чтобы использовать Google Framework. Можно ли поддерживать список указателей на функции для некоторых методов класса, которые будут использоваться для выполнения внутри класса, чтобы их можно было использовать после создания экземпляра? пожалуйста, обратитесь 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
Вы можете использовать страшный указатель на функцию-член:
// 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));
Видеть это Жить на Колиру тоже
for (it = sample.func_list.begin(); it != sample.func_list.end(); ++it) {
(*it)(&sample); // much better
}
Дополнительная универсальность заключается в том, что вы можете обслуживать разные подписи: Жить на Колиру
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)); }
Вы в настоящее время объявили 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);
}
При вызове функции-члена вам понадобится объект, для которого вы хотели бы вызвать его, это означает, что вы — чтобы вызвать функцию-член через указатель на член-функции— должен предоставить объект на месте вызова.
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