Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Компилятор https://www.cyberforum.ru/ cpp/ thread193991.html
Здравствуйте. Пишу компилятор pas->asm на с++ Может кто-то подскажет генератор конструкцый или что-то подобное: <переменная1>+<переменная2> mov...
C или C++(не холивар) C++
Здравствуйте. Участвую в различных олимпиадах по программированию, пишу обычно на C++, используя все его вкусности в виде STL, ООП, темплэйтов и проч. Накануне в двух задачах не уложился в...
x86 интерпретатор исходный код C++
кто-нибудь слышал про интерпретаторы x86? в инете нарыл только что в qemu, bochs есть встроенные интерпретаторы команд x86 процессора, но пока не докопался до них. Нужно самому написать такой...
C++ Крестики Нолики учу си месяц дали задачу... хелп ми плиз! Игра крестики нолики. Игра в крестики нолики вдется на квадратном поле 3*3. Играют двое. Начинают крестики. каждый из игроков, поочередно, ставит свой... https://www.cyberforum.ru/ cpp/ thread193237.html
C++ Алгоритмы и программы по использованию указателей и динамических структур данных https://www.cyberforum.ru/ cpp/ thread193137.html
Здравствуйте! Помогите, пожалуйста, написать задачу. Вот текст:Дан указатель P0 на один из элементов непустого двусвязного списка. Вывести число N — количество элементов в списке, а также указатели...
Функция rand C++
Решить задачу с использованием библиотечной функции rand,заголовочный файл stdlib.h Случайные числа в диапазоне от -32768 до 32768 можно получить с помощью следуйщей фунции int casual () { ...
C++ callback метода класса
Предыстория: нужно последовательно запускать несколько однотипных циклов большой степени вложенности, в теле которых вызывать разные функции. Т.к. вроде бы переписывать циклы (тем более громоздкие...
C++ кривой Безье написать проектную процедуру создания кривой Безье, Желательно в С++ Добавлено через 17 часов 16 минут помогайте срочно надо(( я не знаю как сделать .... ил дайте ссылку на информацию как ее... https://www.cyberforum.ru/ cpp/ thread192259.html
C++ Выявление такого же ай-пи/мак адреса https://www.cyberforum.ru/ cpp/ thread191681.html
Усем здрасти!) имеется необходимость написать приложение, которое, бы присваивало ip адрес сетевой карте и менять ее мак-адресс. Но самое интересное, что приложение должно извещать пользователя о...
C++ КНИГИ Подскажите харошую(лучшую) книгу по С++ ИЛИ Visual C++ Добавлено через 2 часа 45 минут Посрветуйте https://www.cyberforum.ru/ cpp/ thread191642.html
Evg
Эксперт CАвтор FAQ
21146 / 8162 / 628
Регистрация: 30.03.2009
Сообщений: 22,463
Записей в блоге: 30
21.11.2010, 13:41  [ТС] 0

Использование указателя на метод вместо виртуального метода

21.11.2010, 13:41. Просмотров 5496. Ответов 45
Метки (Все метки)

Ответ

Цитата Сообщение от Manjak Посмотреть сообщение
Как окончательно проснусь - набросаю простой вариант
Сейчас у меня всё работает примерно по следующей схеме. Для простоты возьмём окно, которое отображает скачанную из инета картинку. На окне есть поле для картинки и кнопка. Смысл кнопки такой же, как и у браузеров. Если мы ничего не делаем, то кнопка имеет функциональность "Reload" (т.е. инициирует процесс скачивания и отображения картинки). Если идёт процесс скачивания, то кнопка имеет функциональность "Stop" (т.е. прервать текущий процесс скачивания)

Схематично примерно всё выглядит так. Здесь отображаю только код для окна с картинкой (производный класс), потому как базовый класс условно считаем чёрным ящиком, который надо реализовать. Сейчас чёрный ящик реализован через виртуальные методы

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Обработка события нажатия на кнопку Reload/Stop
void __fastcall
TWindowChart::ButtonClick (TObject *Sender)
{
    if (m_IsReloading)
    {
        // KillExecute - метод базового класса для прибития потока
        // Возвращает true, если поток убили, возвращает
        // false, если убить не получилось (к моменту начала прибития поток
        // сам завершился)
        // В любом случае отработает метод Execute3 (см. ниже).
        // Таким образом в конкретно данном случае результат, возвращённый
        // методом KillExecute нам не важен
        KillExecute();
    } else
    {
        ReloadImage();
    }
}
 
// Скачивание и отображение картинки
void
TWindowChart::ReloadImage (void)
{
    // StartExecute - метод базового класса. В процессе своего исполнения
    // он исполнит три метода (виртуальных): Execute1, Executre2 и Execute3.
    //
    // Execute1 исполнится в самом начале в главном процессе и имеет смысл
    // подготовки к исполнению потока. После исполнения данного метода
    // мы выйдем из StartExecute и главный процесс продолжит работать
    // (обрабатывать события) без тормозов
    //
    // Execute2 исполнится в потоке. Он будет исполняться параллельно
    // основному процессу и в этом методе нужно поместить "длительные"
    // действия (скачивание из инета). Пока этот поток тормозит об инет,
    // основной процесс может нормально реагировать на события (двигать
    // окошки и т.п.
    //
    // Execute3 будет исполнен в главном процессе после завершения потока
    // Вызовется этот метод через стандартную очередь сообщений
    // (т.е. наравне со всеми прочими событиями типа нажатия на кнопку)
    // При этом параметром будет передана причина завершения потока:
    // поток завершился самостоятельно, принудительно (через Kill) или
    // по таймауту 
    //
    // ВАЖНО!
    // __ВО ВРЕМЕНИ__ эти три метода исполняются последовательно.
    // Это позволяет не корячиться с синхронизацией для обращения
    // к полям данного класса (m_IsReloading в нашем примере)
    StartExecute (30);  // параметр - время таймаута
}
 
void
TWindowChart::Execute1 (void)
{
    // Подготовительные действия. Вычисляем URL картинки и т.п.
    ...
 
    // На кнопку наносим надпись "Stop"
    ...
 
    // Флажок, который определяет текущую реакцию на нажатие на кнопку
    m_IsReloading = true;
}
 
void __IN_THREAD__
TWindowChart::Execute2 (void)
{
    // Скачиваем данные из инета
    ...
}
 
void
TWindowChart::Execute3 (int reason)
{
    // Через параметр reason передаётся причина завершения потока
 
    // Если поток прервали принудительно, то отображать ничего не надо
    if (reason == "поток умер через Kill")
    {
        goto Finish;
    }
 
    // Если поток умер по истечении времени (таймауту), то выдадим ошибку
    if (reason == "поток умер по таймауту")
    {
        UserError ("таймаут");
        goto Finish;
    }
 
    // Поток успешно завершился
    // Проверяем ошибки: не удалось скачать данные с сервера, данные скачались,
    // но картинка оказалась битая и т.п. Рисуем картинку в случае успеха
    ...
 
  Finish:
    // Завершающие действия
    ...
 
    // На кнопку наносим надпись "Reload"
    ...
 
    // Флажок, который определяет текущую реакцию на нажатие на кнопку
    m_IsReloading = false;
}
В конечном итоге хотелось бы, чтобы код окна остался таким же простым (весь геморрой по работе с потоком унесён в базовый класс). Только использование указателя на метод вместо виртуального метода сделало бы это дело более гибким. Не говоря о том, что такой код было бы проще понимать.

Нынешний вариант тоже работоспособен, потому как если нужно исполнять различные действия, то по дополнительному параметру можно настраивать действия внутри Execute1, ... Т.е. вопрос упирается в удобство. Вторым бонусом работы с указателями будет то, что проще организовывать работу с несколькими потоками

Вернуться к обсуждению:
Использование указателя на метод вместо виртуального метода
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.11.2010, 13:41

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Переопределение виртуального метода
Нужно написать виртуальный метод в родительском классе , который находит площадь круга. Затем...

переопределение виртуального метода
Существует родитель-класс TEditField = class(TObject) protected procedure...

Ошибка создания виртуального метода?
Здравствуйте, хочу сделать так что бы программа(на андроид) рисовала по заданным координатам, но...

Реализовать перегрузку виртуального метода
В класе class1 реализован открытый виртуальный метод деление двух чисел &quot;a&quot; и &quot;b&quot;. Не внося...

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