2015-04-18 2 views
1

Я пытаюсь реализовать что-то вроде шаблона команды для управления серверными компонентами с тем же интерфейсом. Каждый компонент должен реализовать следующий интерфейс.C++ command pattern

class ComponentInterface { 
    public: 
     virtual int start() = 0; 
     virtual int stop() = 0; 
}; 

Каждый производный компонент реализует некоторые конкретные методы.

class Led : public ComponentInterface { 

    public: 
     /** 
     * Implements Interface methods 
     */ 
     int start() { return 0; } 
     int stop() { return 0; } 

    private: 
     int setIntensity(int attrs[], int returns[]) { 
      printf("Set intensity called"); 
      return 1; 
     } 

}; 

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

class ComponentInterface { 
    public: 
     ... 
     // for storing the pointers 
     int (ComponentInterface::*commandsArray[10])(int[], int[]); 
     // to call the member functions 
     int command(int commandId, int attrsList[], int responseList[]) { 
      return (this->*commandsArray[commandId])(attrsList, responseList); 
     } 
} 

class Led : public ComponentInterface { 

    public: 
     Led(float* ledIntensity) { 
      // store the command in the array 
      this->commandsArray[0] = (&Led::setIntensity); 
     } 

     // redefine the array for pointers of this subclass 
     int (Led::*commandsArray[5])(int[], int[]); 

}; 

Я не знаком с C++, и я не понимаю, почему он не работает, у меня есть проблемы при вызове хранимых функций.

При тестировании с devC++ я получаю ошибку сегментации. Когда я попытался проверить его в Visual Studio 2013 (Visual C++) и отладчик, кажется, что в этом ряду

(this->*commandsArray[commandId])(attrsList, responseList); 

, то this объект указывает на ComponentInterface объекта вместо светодиодное объекта.

+1

«У меня проблемы», по сути, бесполезно - какие у вас проблемы? Каковы ошибки компилятора или времени выполнения, которые вы получаете? – Mat

+0

@Mat - Я тестирую его с помощью 'devC++', и я становлюсь« ошибкой сегментации » –

+0

Segfault где? Используйте отладчик, чтобы узнать. Затем исследуйте и добавьте то, что вы нашли на свой вопрос. – Mat

ответ

1

две вещи сразу же неправильно в вашем коде:

  1. Вы не можете «переопределить базовый класс переменной» и эта линия не вполне имеет смысл в производном классе

    // redefine the array for pointers of this subclass 
    int (Led::*commandsArray[5])(int[], int[]); 
    
  2. Это литая неправильно

    this->commandsArray[0] = (&Led::setIntensity); 
    

    это должно скорее быть

    this->commandsArray[0] = static_cast<int (ComponentInterface::*)(int*,int*)>(&Led::setIntensity); 
    

Во всяком случае чище и безопаснее способ добиться того, что вы хотите следующее:

(Отказ от ответственности: тяжелый зачистки вперед, игнорируя все, что не сразу дело в обсуждении)

class ComponentInterface { 
    .. 
    std::vector<std::function<int (int[], int[])>> commandsArray; 
} 

Live Example

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

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