Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.76/449: Рейтинг темы: голосов - 449, средняя оценка - 4.76
146 / 146 / 32
Регистрация: 26.10.2008
Сообщений: 782

Для чего нужны callback-функции

10.04.2009, 17:55. Показов 86843. Ответов 103
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Для чего нужны callback-функции? И можно привести какой-нибуль пример по их использованию.
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.04.2009, 17:55
Ответы с готовыми решениями:

Для чего нужны указатели на функции?
для чего нужны эти указатели на функции... не проще ли вызвать саму функцию, чем заводить под нее указатель и им пользоваться...

Для чего нужны виртуальные функции и виртуальное наследование ?
Для чего нужны виртуальные функции и виртуальное наследование ? Я нашел не сколько статей но не все понял. Заранее спасибо!

Для чего нужны функции void, не возращающие никаких значений?
собственно сабж. выводить текст можно и без функции. а для чего делать что-то, что в дальнейшем и не пригодится в программе? #include...

103
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
03.06.2020, 13:34
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Святогор Посмотреть сообщение
Может мы делаем проще код?
да.

предположим, ты - разработчик GUI библиотеки.
и ты сделал класс кнопок.

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

твою библиотека будет использоваться в различных проектах.
людям нужно отобразить на экране кнопку,
на которую можно будет нажать.

что произойдёт если нажать на кнопку?
это зависит от логики самого проекта.

например, в одном случае, нажатие на кнопку будет означать "подтвердить свои данные".
а в другом - выход из программы.

в разных ситуациях реакция на нажатие кнопки может быть разной.

и вот как ты, разработчик GUI библиотеки, сможешь реализовать такую кнопку,
которая в каждом конкретном случае будет делать что-то своё?
1
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
03.06.2020, 13:39
Святогор, теперь ваш вопрос
Цитата Сообщение от Святогор Посмотреть сообщение
какое преимущество дает возможность отправлять для одной функции аргумент являющийся другой функцией
можно свести к более простому: зачем маме оставлять записку для сына?

И ответ уже не так уж и непонятен, да ведь? Например, мама может быть на работе или заниматься другими делами, и у нее не будет возможности самой купить хлеб.

Так и в программировании. Вызывающая функция может не обладать необходимыми данными или не располагать временем для выполнения этой операции, а вот вызываемая - может. В частности, в примере с сортировкой - передаваемая callback-операция - это компаратор, т.е. метод сравнения двух элементов. Естественно на вызывающей стороне его нельзя выполнить не перетащив к себе заодно и весь алгоритм сортировки. Сортируемые элементы ведь сравниваются по ходу дела. Вот и получается, что вызывающая функция может через передачу компаратора указать в каком порядке сортировать, а вот выполнять компаратор нужно уже вызываемой функции, т.е. самой сортировке.
2
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
03.06.2020, 14:25
Святогор, поведение любого кода имеет точки ветвления. Это логические узлы, которые изменяют поведение выбирая ту или иную ветвь в потоке выполнения, в зависимости от вычисленного результата условного выражения или какого-то ещё события. Когда результат известен на стадии компиляции, программист может менять его перед сборкой программы как настроечный параметр. Если результат вычисляется во время выполнения, то код проявляет изменчивость времени выполнения.
Коллбэк это способ ветвления. Бывает, что в области данной функции нет информации о исполняемом коде, о котором известно лишь, что ему нужно и что он вернёт. В этом случае применяется вызов в котором вызывающая сторона предоставляет код, который ей нужен как клиенту. И это имеет значение. Скажите, у вас будут разные ощущения на фразу "I'll be back" сказанную Николь Кидман в пушистом халатике или Арнольдом Шварценегером с пулеметами в каждой руке? Программа тоже самое чувствует.
1
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
03.06.2020, 18:38
Цитата Сообщение от Святогор Посмотреть сообщение
Очень интересный ответ. Вы обьясняете непонятное через непонятное. Видимо дя выражения "полиморфизм по времени" очень трудно найти простые слова. Полиморфизм означает множество форм, у времени нет форм.
Звучит как анекдот про "в углу скребет мышь". Во-первых, не "полиморфизм по времени", а "полиморфизм времени". Во-вторых, целиком это звучало как "полиморфизм времени выполнения", т.е. полиморфизм, который имеет место/реализуется во время выполнения кода.

В-третьих, не надо рассматривать эти запутанные термины как объяснение. Это лишь названия. А объяснение заключается именно в приведенных примерах. Я привел вам пример qsort. А ISergey расписал вам свой, аналогичный пример с использованием callback. Из этих примеров должно быть хорошо понятно, о чем идет речь. Вы пробовали рассматривать эти примеры?
1
"C with Classes"
2022 / 1404 / 523
Регистрация: 16.08.2014
Сообщений: 5,885
Записей в блоге: 1
03.06.2020, 22:44
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
в углу скребет мышь
я таки реально в углу скрибу мышь, поможешь мне найти мышь?
0
18 / 19 / 4
Регистрация: 27.06.2016
Сообщений: 236
04.06.2020, 21:01
Я прекрасно понимаю как работает вышеприведенный код.
Знаете как выглядят ваши обьяснеия для человека не знакомого с этой темой?
Вот так: а вот представь себе что ты после интегррования стал параметрической функцией четырёх измерений на гомоморфной поверхности и что ты тогда будешь делать в неизотропном пространстве а? Вот и подумай прежде чем вопросы задавать.

Добавлено через 18 минут
Цитата Сообщение от hoggy Посмотреть сообщение
и вот как ты, разработчик GUI библиотеки, сможешь реализовать такую кнопку,
которая в каждом конкретном случае будет делать что-то своё?
Как учили на плюсах. С помощью наследования и виртуальных функций.

Цитата Сообщение от DrOffset Посмотреть сообщение
Так и в программировании. Вызывающая функция может не обладать необходимыми данными или не располагать временем для выполнения этой операции, а вот вызываемая - может.
\
О чём вы говорите? Вызывающая функция замирает в ожидании пока вызываемая работает, по факту времени вызываемая находится внутри вызывающей, что в данном случае может означать что вызывающая функция не имеет времени а у вызываемой его сколько хочешь?
У нас один поток выполнения программы пока вызываемая не сделает свои дела вызывающая будет на паузе.


Цитата Сообщение от _stanislav Посмотреть сообщение
Святогор, один и тот же код получая разные адреса может делать разные вещи, это на самом деле очень выгодая гибкость, когда что то одинаковое делает разное.
И дальше должна быть фраза : таким образом мы получаем выгоду в ..... чём?

Я встречал в интернете такие обьяснения что мол колбэк функция это такая функция которой сказал иди жди пакеты
и она ушла и ждёт а когда появился пакет то возвращает значения а в это время спокойно работает основной код программы.
Это получается что то вроде прерывания . Но такое возможно если у вас несколько потоков один поток циклически опрашиват наличие пакетов а другой в это время работает исполняя основной код программы.
0
04.06.2020, 21:01

Не по теме:

Цитата Сообщение от _stanislav Посмотреть сообщение
я таки реально в углу скрибу мышь, поможешь мне найти мышь?
Это вугскр и белый Logitech у тебя завелись. Я бы купил новый. Нет смысла его скребсти.

0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
04.06.2020, 21:04
Цитата Сообщение от Святогор Посмотреть сообщение
О чём вы говорите? Вызывающая функция замирает в ожидании пока вызываемая работает, по факту времени вызываемая находится внутри вызывающей, что в данном случае может означать что вызывающая функция не имеет времени а у вызываемой его сколько хочешь?
У нас один поток выполнения программы пока вызываемая не сделает свои дела вызывающая будет на паузе.
В данном случае время у них общее, а вот данные - нет. У меня там стоит или.
Впрочем сама концепция "обратный вызов", может использовать и в многопоточной среде, тогда время тоже становится актуальным.

Добавлено через 1 минуту
Цитата Сообщение от Святогор Посмотреть сообщение
Это получается что то вроде прерывания
Прерывание, а точнее его обработчик - это тоже callback.
0
04.06.2020, 21:07

Не по теме:

Цитата Сообщение от Святогор Посмотреть сообщение
Знаете как выглядят ваши обьяснеия для человека не знакомого с этой темой?
Просто считайте, что мой ответ предназначен для людей, знакомых с "этой темой".

0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
04.06.2020, 21:13
Цитата Сообщение от Святогор Посмотреть сообщение
таким образом мы получаем выгоду в ..... чём?
В том, что код может не знать ни чего кроме сигнатуры. Функция сортировки - не плохой пример. Ей не за чем знать как вам хочется сравнивать предоставленные данные. Главное чтобы сравнение отрабатывало корректно и всё. Вы передаёте указатель на код, - он - запускает. Тут всё упрощено, конечно. В более сложных примерах за указателем передаются параметры. Сортировке это не надо, она в контексте и так всё имеет.
Святогор, ещё раз. У вас в коде есть необходимость сделать вычисления. Есть данные - параметры будущего вызова и объект для получения результата вы тоже соорудить можете (if any). Но ваша задача сделать код независимым от конкретного имени функции. Библиотеку вы пишете и хотите, чтобы юзер расширял - как ему угодно. Откуда вам знать что и как он хочет сортировать. По возрастающей, по убывающей... У строк - несколько вариантов сравнения (с учётом, регистра, без учёта регистра, по длине...). Тут дело не в выгоде. Тут дело в реализации возможности, в принципе. И если вы загнаны в угол и не можете использовать полиморфизм другого вида, то если поскрести по сусекам и прочим местам то мышь - хороший вариант. На без рабье и A4tech - станет подспорьем.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.06.2020, 21:33
Цитата Сообщение от Святогор Посмотреть сообщение
Как учили на плюсах. С помощью наследования и виртуальных функций.
такой вариант тоже возможен.
вот только штука в том, что это ничем не отличается от callback подхода.

в варианте с наследованием, тебе нужно создать наследника,
и переопределить виртуальный метод.

в варианте с callback, кол-во буковок меньше:
можно сразу указать конкретную функцию, или метод,
который нужно дёрнуть по событию "на кнопку нажали"

таким образом, вся разница только в количестве текста,
который нужно написать программисту.

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


вот теперь сам по суди, что удобнее и проще:

1. вариант с наследованием:


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <gui/button.hpp>
 
class game_button: public gui::button
{
    template<class ...Args>           // придется позаморачиваться с конструкторами
    game_button(Args&&... args): 
         gui::button( std::forward<Args>(args)... )
    {}
 
    virtual void onClick() 
   {
       std::cout << "click!\n"; // <--- и все это только ради того, что бы напечатать в консольку
    }
};
 
int main()
{
    game_button but;
    gui::start();
}
или вариант с коллбеком:

C++
1
2
3
4
5
6
7
8
9
#include <gui/button.hpp>
 
int main()
{
    gui::button but;
    but.onClick = [](){ std::cout << "click!\n";  };
 
    gui::start();
}

когда вас учили программировать на с++,
вас не забыли обучить одному важному правилу: "не плоди сущности без необходимости" ?
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
04.06.2020, 21:40
Святогор, наследование иногда не катит. В колбэк можно лямбду передать захватив из контекста то, что нужно и так, как нужно. При наследовании, это затруднительно может оказаться. Не всегда заранее известно, сколько и каких параметров нужно определить для конструктора наследника. Можно локальным функтором обойтись, но с наследованием будут проблемы) Хотя, зголиться всегда можно, но колбэк, это удобно иногда. Хотя С-стиль, хуже контроль типов, всё так. qsort отличный пример - пир указателей void *. Но если применять там, где нужно и как нужно, - будет профит.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
04.06.2020, 21:44
Добавлю чуть чуть.
Цитата Сообщение от hoggy Посмотреть сообщение
вот только штука в том, что это ничем не отличается от callback подхода.
А если еще под капот в C++ заглянуть, то окажется, что виртуальные функции в С++ - это просто напросто таблица указателей на callback`и.

Вот этот код,
C++
1
2
3
4
void do_some(Object * obj)
{
    obj->print(); // print - виртуальная функция, obj - указатель на абстрактный класс
}
И этот код
C++
1
2
3
4
5
void do_some(Object * obj)
{
    void (*print)() = obj->vptr[0]; // vptr - указатель на массив указателей на функции, от 0 до N - список виртуальных функций по порядку
    print();
}
- одно и то же. На С можно написать полную эмуляцию виртуальных функций (естественно в рамках одного ABI) и подсунуть
ее на сторону С++, а тот даже и разницы не заметит.
0
18 / 19 / 4
Регистрация: 27.06.2016
Сообщений: 236
04.06.2020, 22:15
Прикольно. Вы в качестве примера привели лямбда функции из с++ 11 кажется так да? Ну ну. Всё яснее и яснее.
Обычно обЪясняют сложное через простое :-) но не тут то было.

Я помню как на 1 курсе мне в соседней ветке объясяняли что такое конструктор.... чего только не наплели каких только терминов не выгрузили тонну... А всего одно предложение: конструктор это кусок кода выполняемый при создании обЪекта, что то вроде автозапуска в виндовс. Всё.. Не нужен ни параграф ни абзац.

У меня есть смутное ощущение что под термином collback понимаются как минимум две разные вещи, это асинхронное программирование и тот самый полиморфизм который тут сказали.

Цитата Сообщение от TheCalligrapher Посмотреть сообщение
В-третьих, не надо рассматривать эти запутанные термины как объяснение. Это лишь названия. А объяснение заключается именно в приведенных примерах.
Вот не скажите , лично я тысячу раз убеждался что в англоязычной среде терминология имеет прямой смысл а не просто ярлыки. Более того пока не найдёшь правильный точный перевод понять в русской адаптации невозможно.

Это в русском языке практикуется такое безобразие когда уважаемые в узких кругах специалисты берут англоязычыне термины или просто слова и дают им наполнение весьма отдалённое от значения самих слов. Главное "ярлык" есть а по нему найдёте что такое колоноскопия в физике плазмы.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
04.06.2020, 22:23
Цитата Сообщение от Святогор Посмотреть сообщение
У меня есть смутное ощущение что под термином collback понимаются как минимум две разные вещи, это асинхронное программирование и тот самый полиморфизм который тут сказали.
Нет конечно.
callback - это способ сообщить постороннему коду что надо делать. Этот посторонний код может выполняться и асинхронно, и\или синхронно, для понимания концепции это не важно.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13210 / 6843 / 1824
Регистрация: 18.10.2014
Сообщений: 17,306
04.06.2020, 22:25
Цитата Сообщение от Святогор Посмотреть сообщение
Это в русском языке практикуется такое безобразие когда уважаемые в узких кругах специалисты берут англоязычыне термины или просто слова и дают им наполнение весьма отдалённое от значения самих слов.
Абсолютно во всех языках значения терминов как правило далеки от повседневного значения самих слов. Такова естественная особенность технической терминологии. Попытки интерпретации значений терминов при помощи толкового словаря обычного языка могу привести разве что к юмористическим результатам.
0
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
04.06.2020, 22:30
В случае сортировки мы говорим:
"сортировка - сортируй по возрастанию. Вот тебе функция, которая сравнивает элементы таким образом, чтобы у тебя это получилось." - это пример использования с параметрическими алгоритмами

В случае пула потоков мы говорим:
"пул потоков, вот тебе функция-задача, выполняй ее когда будешь свободен" - это пример использования с многопоточностью

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

Все это примеры использования callback`ов.
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
04.06.2020, 22:42
Цитата Сообщение от Святогор Посмотреть сообщение
Прикольно. Вы в качестве примера привели лямбда функции из с++ 11 кажется так да? Ну ну. Всё яснее и яснее.
Святогор, ость ощущение, что вы пытаетесь сертифицировать объясняющих вам людей. В данной точке вуглускреатив вуглускрит искрами мышеизложенного.
Цитата Сообщение от Святогор Посмотреть сообщение
А всего одно предложение: конструктор это кусок кода выполняемый при создании обЪекта

Удачи.
1
19501 / 10106 / 2461
Регистрация: 30.01.2014
Сообщений: 17,825
04.06.2020, 22:49
IGPIGP, да, пожалуй вы правы. Такое ощущение, что на приемке у комиссии, которая всеми силами пытается найти недостатки. Цели конструктивной работы, естественно, не преследуются. "Работать не надо, надо закрыть".

Если кто-то действительно хочет что-то понять, даже если первоначальное объяснение не совсем удачное, он задает уточняющие вопросы и, в итоге, понимает. А тут этого нет вообще. Пожалуй тоже от темы отпишусь, т.к. все это похоже на троллинг.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.06.2020, 23:07
Цитата Сообщение от Святогор Посмотреть сообщение
У меня есть смутное ощущение что под термином collback понимаются как минимум две разные вещи, это асинхронное программирование и тот самый полиморфизм который тут сказали.

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

ключевое слово: независимым

вот например, есть функция копирования файлов и каталогов:
C++
1
copy(const path& from, const path& to);
с нею всё хорошо.
однако копирование больших папок - дело не быстрое.
и хочется как то отобразить на экране прогресс-бар для пользователей.

причем мы не хотим, что бы наша функция копирования
была прибита гвоздями к какому то одному проекту.
мы хотим использовать её повторно в самых разных проектах.

например, в одном проекте нужно рисовать кирпичики в окошке.
а в другом - просто печатать процентики в консоли.

я просто добавляю коллбек:
C++
1
copy(const path& from, const path& to, const callback& foo);
функция copy периодически запускает коллбек,
в котором она сообщает, сколько процентов уже скопировалось.
ей все равно, как именно каллбек поступит с полученной информацией.

в каком то конкретном проекте я просто печатаю проценты в консольку:

C++
1
2
3
4
5
6
7
8
9
10
11
#include <tools/filesystem>
 
int main()
{
    const auto progress = [](const float percent)
    {
        std::cout << "copying ... " << percent << "%\n";
    };
 
    tools::copy("C:\\game" "C:\\game2", progress);
}
минимум кода. просто и удобно.
функция copy не зависит ни от консольки, ни от виндузятных окон,
ни от проекта вообще.

а как бы ты реализовал такую вот независимую от остального проекта функцию копирования?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
04.06.2020, 23:07

приведите пожалуйста реальный прмиер: для чего нужны дружественные функции?
приведите пожалуйста реальный прмиер: для чего нужны дружественные функции?

For_each и аргументы callback-функции; Как передать callback'у больше одного аргумента
Изучаю контейнеры и алгоритмы stl по Майерсу . С непривычки слегка охренел и запутался в них . В общем есть у меня простой вызов...

callback функции не для кнопок на экране, а для клавиш на клав. и мышке. Как?
Я так понимаю, что в WIN API все действия делаются асинхронно через callback функции. Но как инициировать действие для клавиш клавиатуры...

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

Для чего нужны указатели?
Кто может объяснить для чего нужны указатели и смысл их? в интернете одна муть и еще для чего нужно new delete


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Алиса нашла кучу ошибок компиляции и запуска в проекте, который без проблем компилировался и запускался)))
anaschu 30.06.2026
Я пока посмеюся, но завтра проверю. А вообще интерсно. Дал алисе файл, в котором точно нет ошибок компиляции и запуска, и попросил их найти. Нашла кучу))) Критические ошибки, мешающие компиляции и. . .
сукцессия 16. Общий обзор, в основном что бы другие ии поняли
anaschu 29.06.2026
# Передаточный документ: модель микоризной сукцессии (для нового чата) Этот документ предназначен для того, чтобы новый чат Claude мог продолжить работу без необходимости заново разбираться в. . .
сукцессия 15 неявная схема
anaschu 29.06.2026
Алиса Калибровка параметров симбиотической модели: технический обзор Содержание: Введение Постановка проблемы Технические аспекты реализации Процесс внедрения изменений
сукцессия 14. Обновленная схема модели
anaschu 28.06.2026
ГЛОБАЛЬНАЯ ОПИСАТЕЛЬНАЯ СПЕЦИФИКАЦИЯ ЭКОСИСТЕМНОЙ МОДЕЛИ «SOIL CHEMISTRY & MYCORRHIZA 2. 0» https:/ / ibb. co/ NnkGpfMd Представленная интегрированная схема описывает непрерывную нелинейную. . .
сукцессия 13. Питон модель трехзонного мицелия, пока что в основном арбускулярного
anaschu 28.06.2026
## Разработка агентной модели микоризной сукцессии: от выявления артефактов к созданию комплексной системы ### Аннотация Представлено исследование по разработке агентной модели микоризной. . .
сукцессия 12. краткий список проверок модели перед запуском.
anaschu 27.06.2026
Скрытые отказы в моделях систем динамики (SD-models) экологических систем: два случая из практики Контекст Разбирался прототип модели систем динамики (SD-модели) микоризной сукцессии: пять. . .
Сукцессия 11. Проверка орудий перед войной: разработка через тестирование
anaschu 27.06.2026
Как не дать модели соврать самой себе: проверки для симуляции микоризной сукцессии Введение Когда вы строите математическую модель живой системы — грибов, растений, почвы — главная опасность. . .
10 сукцессия. Питон код войны грибов и растений
anaschu 27.06.2026
import numpy as np class PlantAgent: def __init__(self, name, strategy, initial_biomass): self. name = name self. strategy = strategy # "greedy" (широколиственные) или. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru