![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
OlegIT |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 684 Регистрация: 5.4.2006 Репутация: нет Всего: нет |
В классе имеются несколько однотипных функций. Как сделать список из этих функций в QList или vector?
|
|||
|
||||
Lukkoye |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
http://rextester.com/XFBRA12764
Первый способ работает быстрее. Но менее гибкий. Создается указатель на функцию-член, в котором фигурирует имя класса, что делает невозможным хранить в одном списке указатели на методы разных классов. Второй способ более мощный, гибкий - создание делегата. Делегат - это особый класс функторов (std::function), способный осуществлять запуск свободной функции или функции члена, без необходимости "помнить" к какому классу относится функция-член. Грубо говоря, std::function это что-то вроде кютешных слотов-сигналов, вот только защита времени компиляции и работает на порядок быстрее. |
|||
|
||||
OlegIT |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 684 Регистрация: 5.4.2006 Репутация: нет Всего: нет |
Спасибо.
Как я понимаю Ваша ссылка на ресурс, где можно запускать свой код, вставляя его в окно редактора. Так? Это сообщение отредактировал(а) OlegIT - 7.7.2014, 11:20 |
|||
|
||||
OlegIT |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 684 Регистрация: 5.4.2006 Репутация: нет Всего: нет |
Протестировал Ваш код в Visual Studio и в Qt5.3. Ошибки такие, компилятор не знает, что есть такое emplace_back (хотя внутри vector он есть) и bind. И на функцию launch() по полной выругался. Поместил в буфер функции с помощью push_back, но вызвать их не получается.
У меня другой ещё вопрос. Это всё мне нужно для предотвращения зацикливания, мои однотипные функции могут вызываться последовательно и вернутся к первоначальной функции. Что бы этого избежать, я создаю буфер из этих функций, а потом, в основном цикле программы, выполняю вызов функций из этого буфера. Но при вызове может оказаться, что буфер функций пополнился. Не будет тут проблемы? Может по другому это можно сделать? |
|||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
||||
|
||||
OlegIT |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 684 Регистрация: 5.4.2006 Репутация: нет Всего: нет |
||||
|
||||
NoviceF |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 313 Регистрация: 13.3.2012 Где: Ростов-на-Дону Репутация: нет Всего: 2 |
Это вопрос из области многопоточности. В случае если к структуре данных имеют доступ два и более потоков, нужно синхронизировать доступ к ней при помощи примитивов синхронизации, таких как мьютексы, rwlock, и т.п. То есть, перед тем, как ты начинаешь вызывать функции коллекции, ты захватываешь мьютекс, и ни один другой поток не сможет получить доступ к этой коллекции, пока ты мьютекс не освободишь. Все потоки, что будут пытаться внести изменения в коллекцию или выполнить чтение из неё, будут блокироваться на вызове функции захвата мьютекса, и разблокируются (по одному) только тогда, когда поток, совершающий обход коллекции мьютекс освободит. |
|||
|
||||
Lukkoye |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 86 Регистрация: 23.3.2013 Репутация: 1 Всего: 1 |
Вижал студия из коробки умеет std::function начиная с версии 10 Насчет Qt: 1. Если вы используете систему сборки QMake, пропишите в файле сценария сборки имя_вашего_проекта.pro следующий ключ: QMAKE_CXXFLAGS += -std=gnu++1y либо QMAKE_CXXFLAGS += -std=c++0x 1. Если вы используете систему сборки Сmake, пропишите в файле сценария сборки CMakeLists.txt set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++1y ") либо set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") Данный ключ активирует поддержку нововведений в стандарте языка. По поводу "зацикливаний":
Разумеется будут. Каноничную реализацию можно подглядеть рассматривая устройство какой нибудь "EventSystem". Если вкратце: есть отдельный класс, называемый "Eventsystem ", который хранит внутри себя несколько списков: 1. Желающие добавиться. 2. Желающие удалиться. Этот список представляет собой пару: <делегат, вкл/выкл> Eventsystem в цикле бежит по рабочему циклу, и запускает одного за другим делегаты. Допустим, запуск делегата приводит в действие функцию, которая пытается добавить в Eventsystem новый делегат - он добавляется в список "желающих добавиться". Рабочий же список остается без изменений. Если же запуск делегата приводит в действие функцию, которая напротив, пытается удалить делегат - он просто помечается как "выкл", и Eventsystem знает, что его использовать нельзя. Больше он уже не будет запущен. Если же претендент на удаление обнаружится в списке "желающих добавиться" - можно удалить оттуда сразу же. После того, как весь рабочий цикл завершился, только тогда Eventsystem добавляет в рабочий список новеньких, а так же выбрасывает всех тех, кто помечен, как "выкл". Кроме того, поскольку запуски делегатов происходят в одном единственном месте: в Eventsystem, там удобно ставить защиту для многопоточного режима, а так же легко пропасти - был ли один и тот же делегат вызван дважды. То бишь, легко отловить факт рекурсивных вызовов, и зацикливания. Это сообщение отредактировал(а) Lukkoye - 8.7.2014, 19:26 |
|||
|
||||
OlegIT |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 684 Регистрация: 5.4.2006 Репутация: нет Всего: нет |
Спасибо за разъяснения. С делегатами и двумя очередями понятно. Не понятно где выполнять вызовы, обработку списка и где "Eventsystem добавляет в рабочий список новеньких"?
Это сообщение отредактировал(а) OlegIT - 9.7.2014, 13:41 |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |