Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
Любитель чаепитий
3587 / 1687 / 519
Регистрация: 24.08.2014
Сообщений: 5,709
Записей в блоге: 1
1

Идеи реализации класса Menu

05.07.2016, 13:58. Показов 1626. Ответов 8
Метки нет (Все метки)

Добрый день. В общем хочу разработать шаблонный класс Menu, чтобы постоянно не писать switch{}, но не знаю, как лучше сделать, суть в том, что есть несколько вариантов, а какой лучше и легче по реализации я понять не могу.
1. Сделать класс Menu_item, в котором будет содержаться строка(название пункта меню) и функция, которую надо вызвать при выборе этого пункта.
Примерно:
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
template<class T>
class Menu_item
{
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    Menu_item
            (
                std::string name_item,
                T func
            )
            :
            name(name_item),
            func(func)
    {}
    //-----------------------------------------------------------------------------------
    template<class... Args>
    void operator()(Args... arg)
    {
        func(arg...);
    }
    //-----------------------------------------------------------------------------------
private:
    //-----------------------------------------------------------------------------------
    T func;
    std::string name;
    //-----------------------------------------------------------------------------------
};
/////////////////////////////////////////////////////////////////////////////////////////
void func(int a, int b)
{
    std::cout << a + b << std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    Menu_item<void(*)(int,int)> m{"asd",func};
    m(1,4);
}

2. Сделать тоже самое, только с std::function<>
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <functional>
/////////////////////////////////////////////////////////////////////////////////////////
template<class T>
class Menu_item
{
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    Menu_item
            (
                std::string name_item,
                std::function<T> func
            )
            :
            name(name_item),
            func(func)
    {}
    //-----------------------------------------------------------------------------------
    template<class... Args>
    void operator()(Args... arg)
    {
        func(arg...);
    }
    //-----------------------------------------------------------------------------------
private:
    //-----------------------------------------------------------------------------------
    std::function<T> func;
    std::string name;
    //-----------------------------------------------------------------------------------
};
/////////////////////////////////////////////////////////////////////////////////////////
void func(int a, int b)
{
    std::cout << a + b << std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    Menu_item<void(int,int)> m{"asd",func};
    m(1,4);
}

3. Сделать всё в одном классе, без всяких итемов и прочего.

Это лишь мои варианты. Если у вас есть свои варианты или дополнение к моим, то пишите, так же буду рад любым советам по теме.

Ещё хотелось бы сделать так, чтобы при надобности совать меню в меню.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.07.2016, 13:58
Ответы с готовыми решениями:

Отделение интерфейса от реализации класса: компиляция кода реализации
Доброго времени суток, У меня возникла проблема с отделением интерфейса от реализации класса....

нужны идеи в реализации кода
В общем если кто подскажет хоть примерно как это должно выглядеть буду очень благодарен. Или просто...

Как передать в метод класса Menu указатель на метод дочернего класса?
Как передать в метод базового класса указатель на метод дочернего: class Menu() { protected: ...

идеи, идеи, идеи для начинающих
доброй ночи, уважаемые форумчане. перейдем сразу к делу =) в общем, собираюсь с 2 одногруппниками...

8
Don't worry, be happy
17176 / 10058 / 1936
Регистрация: 27.09.2012
Сообщений: 25,059
Записей в блоге: 1
05.07.2016, 14:03 2
Лучший ответ Сообщение было отмечено GbaLog- как решение

Решение

Цитата Сообщение от GbaLog- Посмотреть сообщение
Если у вас есть свои варианты или дополнение к моим, то пишите, так же буду рад любым советам по теме.
C++
1
2
3
4
class Menu{
//...
vector<pair<string, function<Type>>> mItems;
};
Это третий вариант?
Недавно реализовывали подобное как раз.
Работает нормально.
Что-то подобное для использования:
C++
1
2
menu.addItem("bla-bla-bla", [](){/**/});
menu.show();
1
Любитель чаепитий
3587 / 1687 / 519
Регистрация: 24.08.2014
Сообщений: 5,709
Записей в блоге: 1
05.07.2016, 14:09  [ТС] 3
Croessmah, Ну я для этого и сделал класс Menu_item, чтобы в вектор эти итемы пихать в Menu. Я забыл класс Menu набросать. Вот это fail.

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/////////////////////////////////////////////////////////////////////////////////////////
class Menu
{
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    Menu();
    //-----------------------------------------------------------------------------------
    template<class T>
    void        add(Menu_item<T> item)
    {
        m_items.push_back(item);
    }
    //-----------------------------------------------------------------------------------
    ...
    //-----------------------------------------------------------------------------------
private:
    //-----------------------------------------------------------------------------------
    std::vector<Menu_item> m_items;
};
/////////////////////////////////////////////////////////////////////////////////////////
0
Don't worry, be happy
17176 / 10058 / 1936
Регистрация: 27.09.2012
Сообщений: 25,059
Записей в блоге: 1
05.07.2016, 14:12 4
Цитата Сообщение от GbaLog- Посмотреть сообщение
Ещё хотелось бы сделать так, чтобы при надобности совать меню в меню.
Ну, в нашем меню это выглядит так:
C++
1
menu.addItem("bla-bla-bla" [&menu2](){menu2.show();}
1
Любитель чаепитий
3587 / 1687 / 519
Регистрация: 24.08.2014
Сообщений: 5,709
Записей в блоге: 1
05.07.2016, 14:29  [ТС] 5
Croessmah, Собственно, новый вопрос, как член класса сделать шаблонным, не делая шаблонным весь класс?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/////////////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <string>
#include <functional>
#include <vector>
/////////////////////////////////////////////////////////////////////////////////////////
class Menu
{
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    Menu();
    //-----------------------------------------------------------------------------------
    template<class T>
    void        add(std::string name,std::function<T> item)
    {
        m_items.push_back(std::make_pair(name,item));
    }
    //-----------------------------------------------------------------------------------
    template<class... Args>
    void        get(int n,Args... args)
    {
        m_items[n](args...);
    }
    //-----------------------------------------------------------------------------------
private:
    //-----------------------------------------------------------------------------------
    template<class T>
    std::vector<std::pair<std::string,std::function<T>> m_items;
};
/////////////////////////////////////////////////////////////////////////////////////////
void func(int a, int b)
{
    std::cout << a + b << std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    Menu menu;
    menu.add("bla",std::function<void(int,int)>(func));
    menu.get(0,1,2);
}
Может я что-то не так делаю, но не вижу, что именно.
0
Don't worry, be happy
17176 / 10058 / 1936
Регистрация: 27.09.2012
Сообщений: 25,059
Записей в блоге: 1
05.07.2016, 14:33 6
Цитата Сообщение от GbaLog- Посмотреть сообщение
как член класса сделать шаблонным, не делая шаблонным весь класс?
В Вашем случае придется писать (или использовать готовую)
реализацию type erasure, ну или как-то по другому выкручиваться.
Зачем здесь вообще шаблон?
Почему не просто std::function<void()>?
0
Любитель чаепитий
3587 / 1687 / 519
Регистрация: 24.08.2014
Сообщений: 5,709
Записей в блоге: 1
05.07.2016, 14:49  [ТС] 7
Croessmah, Ну как же? А аргументы? Если просто void() сделать, то аргументы уже не всунуть никак.
0
Don't worry, be happy
17176 / 10058 / 1936
Регистрация: 27.09.2012
Сообщений: 25,059
Записей в блоге: 1
05.07.2016, 14:51 8
Цитата Сообщение от GbaLog- Посмотреть сообщение
Если просто void() сделать, то аргументы уже не всунуть никак.
Адаптеры же. Вон выше в лямбду захватывается объект menu2
0
Любитель чаепитий
3587 / 1687 / 519
Регистрация: 24.08.2014
Сообщений: 5,709
Записей в блоге: 1
05.07.2016, 15:01  [ТС] 9
Что-то я совсем запутался. Ну ладно, утро вечера мудренее.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.07.2016, 15:01

Трудности в реализации класса
Не могу понять, почему не работают конструкторы класса... Прошу понятного объяснения=) вот код 1...

Детали реализации конструктора класса
Есть конструктор условного класса картинки и я не совсем понимаю нескольких вещей: #include...

Отделение интерфейса класса от реализации
Осваиваю раздел одной книги &quot;Отделение интерфейса класса от реализации&quot;. То что получилось можно и...

Ошибка реализации класса String
#include &lt;iostream&gt; using namespace std; class String { private: char *pStr; int _size;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.