2015-01-23 4 views
0

Я получаю следующую ошибку компилятора, когда я использовал указатель нестатической функции в аргументе конструктора в методе myclass_2, void load (void).C++, Передача нестатического указателя функции в конструкторе класса

Ссылка на не-статической функции члена должна быть вызвана

Если изменить функцию статической силы нагрузки (пустот) без ошибок. но мне нужна нестатическая функция, мне нужно работать с некоторой глобальной переменной в функции загрузки. Любая помощь была бы оценена.

class myclass{ 
public: 
    //_load_event_handler 
    vector<Function> _handler_one; 
    vector<Function> _handler_two; 
    vector<Function> _handler_three; 

    void register_for_load_event(void(*fun)(void)){ 
     this->_handler_three.push_back(fun); 
    } 

    void register_for_dowork_event(void(*fun)(void)){ 
     this->_handler_one.push_back(fun); 
    } 
    void register_for_end_event(void(*fun)(void)){ 
     this->_handler_two.push_back(fun); 
    } 
    void run (char **fileNames) 
    { 
     for (int i = 0; i< _handler_one.size();i++) 
      _handler_one[i](); 


     for (int i = 0; i< _handler_two.size();i++) 
      _handler_two[i](); 


     for (int i = 0; i< _handler_three.size();i++) 
      _handler_three[i](); 
    } 


}; 

class myclass_2 
{ 
public: 
    myclass *ptrmyclass; 
    void load(void) 
    { 
     cout << "load function start" << endl; 

     //some code here 
    } 
    myclass_2(myclass *_ptrmyclass) 
    { 
     ptrmyclass = _ptrmyclass; 
     ptrmyclass->register_for_load_event(load); 

    } 
    void foo(vector<string> vect) 
    { 
     cout<< "is stop word called" << endl; 
    } 
}; 
+4

'недействительным (* весело) (аннулируются)' не является указателем на функцию члена, так что он может связываться только свободных функций или статических членов. Вместо этого попробуйте использовать 'std :: function '. – user657267

+0

Можете ли вы, пожалуйста, сжать свой пример так, чтобы у нас был http://sscce.org/ – Klaus

ответ

1

Является ли это то, что вам нужно?

Модификации:

  1. Я не вижу, что Function в вопросе поэтому я полагаю, что быть std::function<void()>.
  2. ввод register_for_load_event должен быть допустимым функциональным объектом, поэтому ему нужен bind.

using namespace std; 
class myclass{ 
public: 
    //_load_event_handler 
    typedef std::function<void()> Function; // -------- #1 
    vector<Function> _handler_one; 
    vector<Function> _handler_two; 
    vector<Function> _handler_three; 

    void register_for_load_event(Function fun){ 
     this->_handler_three.push_back(fun); 
    } 

    void register_for_dowork_event(Function fun){ 
     this->_handler_one.push_back(fun); 
    } 
    void register_for_end_event(Function fun){ 
     this->_handler_two.push_back(fun); 
    } 
    void run (char **fileNames) 
    { 
     for (int i = 0; i< _handler_one.size();i++) 
      _handler_one[i](); 


     for (int i = 0; i< _handler_two.size();i++) 
      _handler_two[i](); 


     for (int i = 0; i< _handler_three.size();i++) 
      _handler_three[i](); 
    } 


}; 

class myclass_2 
{ 
public: 
    myclass *ptrmyclass; 
    void load(void) 
    { 
     cout << "load function start" << endl; 

     //some code here 
    } 
    myclass_2(myclass *_ptrmyclass) 
    { 
     ptrmyclass = _ptrmyclass; 
     ptrmyclass->register_for_load_event(bind(&myclass_2::load, this)); // -------- #2 

    } 
    void foo(vector<string> vect) 
    { 
     cout<< "is stop word called" << endl; 
    } 
}; 
+0

Спасибо, это сработало нормально, но что произойдет, если load примет некоторые параметры, такие как void load (char ** имя_файла). что я должен изменить на «ptrmyclass-> register_for_load_event (bind (& myclass_2 :: load, this)); Еще раз спасибо за вашу большую помощь –

+0

Хорошо, предположим, что теперь это 'myclass_2 :: load (char ** filename)'; если вы хотите создать объект 'std :: function ', тогда вам нужно «bind (& myclass2 :: load, this, filename)»; есть два параметра для 'bind', так как' myclass_2 :: load (char ** filename) 'на самом деле' myclass_2 :: load (myclass_2 * ptr, char ** имя_файла) 'при выполнении. Чтобы узнать больше, проверьте http://en.cppreference.com/w/cpp/utility/functional/bind. Keypoint: Цель 'bind' заключается в создании объекта функции, который может быть сохранен в' std :: function'. –

3

Убедитесь Function является std::function<void()>, а затем изменить register_for_load_event взять Function вместо того, что она занимает в настоящее время. Наконец, назовем его так:

ptrmyclass->register_for_load_event(std::bind(&myclass_2::load, this)); 

std::bind() необходима потому, что Function является нульарной (не принимает никаких аргументов), но myclass_2::load() требует один аргумент: неявное this (потому что она не является статичной, поэтому требуется экземпляр myclass_2 . «Связывание» функция-член позволяет обеспечить this указатель на связывания времени, но задержка вызова функции до позже, когда не требуется никаких аргументов.

+0

. Вы должны объяснить, почему необходимо использовать 'std :: bind' – gurka

+0

@gurka: достаточно справедливо, я сделал это сейчас. –

Смежные вопросы