crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

lanz
  опции профиля:
сообщение 26.3.2013, 13:27
Сообщение #1


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


В общем суть такова, есть некоторое количество(N) классов, наследующих от общего предка.
У предка есть интерфейс управления для обработки команд.
Раскрывающийся текст
class Base {
    public:
        virtual void Command (QString, QVariant);
};

Естественно конкретные реализации по разному обрабатывают команды.
В первом приближении примерно так:
Раскрывающийся текст
class DerivedN {
    public:
        virtual void Command (QString, QVariant) {
            switch (QString) {
                ...
                ...
            }
        };
};

Естественно это не очень красиво, поэтому сразу второе приближение:
Раскрывающийся текст
class DerivedN {
    public:
        virtual void Command (QString, QVariant) {
            this->map[QString] (QVariant);
        };
};

В map хранятся указатели на функции члены. Естественно мне захотелось вынести все это в базовый класс.
Раскрывающийся текст
class Base {
    public:
        void Command (QString, QVariant) {
            if (this->processors.contains (QString)) {
                this->processors[QString] (this, QVariant);
            };
        };
    protected:
        typedef std::function<void (Base*, QVariant)> CommandProc;
        QMap<QString,CommandProc> processors;


Загвоздка в том что мы не можем добавлять функции-члены наследующих классов в список. Можно конечно обойтись списком свободных функций,
но интересно, как описать Map который будет содержать функции члены не только базового но и производных классов?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
Iron Bug
  опции профиля:
сообщение 26.3.2013, 22:43
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Вот, по-быстрому написала, как в С++11 это сделать можно.
Это без Qt(я её не юзаю), но не суть. Можно любые классы и контейнеры использовать, это не принципиально.
У меня заюзан простой map и функция, принимающая int, для примера.
В GCC компилируется с опцией -std=c++11.
Раскрывающийся текст
#include <map>
#include <string>
#include <stdio.h>
#include <functional>

using namespace std;

class Base
{
public:
        typedef std::function<void(int d)> CommandProc;
        typedef map<string,CommandProc> map_type;

protected:
        map_type processors;
public:
        Base() {
                processors.insert(map_type::value_type("BaseCommand",std::bind(&Base::BaseCommand, this, std::placeholders::_1)));

        }
        void Command (string str, int value) {
                map_type::iterator iter = processors.find(str);
                if(iter != processors.end())
                        (iter->second)(value);
        };
protected:
        void BaseCommand(int value) {
                printf("this is Base::BaseCommand with argument %d\n",value);
        }
};

class Child1 : public Base
{
protected:
        void MyCommand(int value) {
                printf("this is Child1::MyCommand with argument %d\n",value);
        }
public:
        Child1() {
                processors.insert(map_type::value_type("MyCommand",std::bind(&Child1::MyCommand, this, std::placeholders::_1)));
        }
};

class Child2 : public Base
{
protected:
        void MyCommand(int value) {
                printf("this is Child2::MyCommand with argument %d\n",value);
        }
public:
        Child2() {
                processors.insert(map_type::value_type("MyCommand",std::bind(&Child2::MyCommand, this, std::placeholders::_1)));

        }
};


int main(int argc, char* argv[])
{
        Child1 test1;
        test1.Command("BaseCommand",10);
        test1.Command("MyCommand",10);
        Child2 test2;
        test2.Command("BaseCommand",20);
        test2.Command("MyCommand",20);
}


Сообщение отредактировал Iron Bug - 26.3.2013, 22:45
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- lanz   Архитектурный вопрос   26.3.2013, 13:27
- - Влад   Вот так и описать. А заполнение этого мэпа происхо...   26.3.2013, 13:37
- - lanz   ЦитатаВот так и описать. Не выходит. Цитатаerror C...   26.3.2013, 14:10
|- - Влад   Цитата(lanz @ 26.3.2013, 15:10) Так поним...   26.3.2013, 14:21
- - lanz   Downcast-ить то его можно, только проблема в том ч...   26.3.2013, 14:59
- - lanz   Сделал так: Раскрывающийся текстclass Base : p...   26.3.2013, 16:16
- - Алексей1153   lanz, все названия функций - в текстовом виде, все...   26.3.2013, 18:04
- - Iron Bug   Вот, по-быстрому написала, как в С++11 это сделать...   26.3.2013, 22:43
- - lanz   ЦитатаВот, по-быстрому написала Настоящая черная ...   27.3.2013, 8:39
|- - Iron Bug   Цитата(lanz @ 27.3.2013, 11:39) Насколько...   27.3.2013, 10:53
- - Алексей1153   Цитата(lanz @ 27.3.2013, 11:39) стати нас...   27.3.2013, 13:21
- - lanz   Цитатаделай для этого отдельный быстрый метод без ...   27.3.2013, 13:45
- - Алексей1153   lanz, а где, что и в каких объёмах будет гоняться ...   27.3.2013, 13:51
- - lanz   Графики кривых, 5-10К точек, хотелось бы хотябы 10...   27.3.2013, 14:43
|- - Iron Bug   Цитата(lanz @ 27.3.2013, 17:43) Как кстат...   27.3.2013, 19:37
- - Алексей1153   lanz, ну тут, само собой, лучше оставить лазейку д...   27.3.2013, 18:21


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 10.7.2025, 16:37