2015-03-26 4 views
1

Вот моя проблема:C++ указатели в производных классов

У меня есть базовый класс, содержащий метод, что эта функция «Регистры» класс для определенной строки ID, используя указатель на функцию. Мне удалось заставить его работать, но мне нужны производные классы, чтобы иметь возможность использовать этот механизм. Компилятор заставил меня указать указатели на функции, используя имя класса, которое содержит вызываемую функцию (нотация BaseClass::*). Очевидно, что это не сработает, когда я создаю производный класс.

Вот упрощенный код, который я в настоящее время есть в базовом классе (у меня есть она разделилась между .hh и .cc файлы - вот почему separeted реализация):

class BaseClass{ 
    public: 
     BaseClass(); 
    private: 
     std::map<std::string, void (BaseClass::*)(argType*)> actionMap; 

     void registerAction(void (BaseClass::*)(argType*), std::string actionID); 
} 

BaseClass::BaseClass(){ 
    std::string actionID = "myAction"; 
    void (BaseClass::*fcnPointer)(argType*); 
    fcnPointer = &BaseClass::sendEthernetFrame; 

    registerAction(fcnPointer, actionID); 
} 

void BaseClass::registerAction(void (BaseClass::*actionHandler)(argType*), std::string actionID){ 
    actionMap.insert (std::pair<std::string,void (BaseClass::*)(argType*)>(actionID ,actionHandler)); 
} 

Что мне нужно, чтобы как-то умеет хранить и обращаться к указателям функций различных классов в одном списке и иметь возможность всем называть их на самом высоком уровне цепочки наследования (каждый производный класс может добавлять свои собственные функции, которые необходимо будет зарегистрировать).

Я нахожу очень странным, что я не могу хранить указатели функций другого класса как один тип, поскольку указатели - это просто адреса в конце, не так ли?

+0

Не думаю, что это можно сделать без использования стирания типа типа 'std :: function'. – 5gon12eder

ответ

1

Вы не сможете использовать для этого нестатические методы класса. В C++ не существует понятия «замыкания», которое позволяет назначить указатель производного метода и указатель метода базового класса. Вам придется использовать другой дизайн. Например, вместо этого вы можете сохранить список указателей объектов BaseClass (так как они вам нужны в любом случае для вызова метода нестатического класса), и при необходимости вы можете вызвать метод virtual для этих объектов и присвоить каждому производному классу этот метод по мере необходимости.

+0

Ну, проблема в том, что я заранее не знаю, какие методы будут в производных классах. Идея состоит в том, что пользователь может создать производный класс и добавить к нему функцию. Затем, зарегистрировав его, функция, закодированная в самом базовом классе, может учитывать эту вновь определенную функцию (на основе идентификатора строки). Ну, я думаю, мне придется попытаться придумать другой дизайн. –

1

Если вам не нужна коллекция BaseClass, вы можете использовать шаблон вместо этого и передать производный тип в шаблон.

template <typename DERIVED> 
class BaseClass { 
    std::map<std::string, void (DERIVED::*)(argType*)> actionMap; 
protected: 
    void registerAction(
     void (DERIVED::*)(argType*), std::string actionID); 
    //... 
}; 

class Derived : public BaseClass<Derived> { 
    //... 
    Derived() { 
     registerAction(&sendEthernetFrame, "myAction"); 
    } 
}; 
Смежные вопросы