Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
1 / 1 / 1
Регистрация: 28.04.2013
Сообщений: 35

Вызов функции с не заданными параметрами из объекта класса

10.09.2014, 02:11. Показов 938. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу небольшое API, для себя. Сделал следующие: программист указывает объекту класса, имя пакета и какая должна будет вызваться функция, если этот пакет будет получен от сервера.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void do_msg(int _sock, char *msg)
{
  std::cout << "\nmsg" << msg;
}
 
int main()
{
  OriServer Server;
  Server.CreateServer(500);
  Server << "msg" << do_msg;
  Server.RunServer();
  return 0;
}
Как видно, функция передаётся в Server и помещается в какой-то листинг. После вызывается, если будет пакет "msg".
Это всё хорошо, но параметры функции do_msg заданы моим API, do_msg(int, char *). Т.е задано это таким образом:
C++
1
typedef void (* PacketFunc_Sock_Buffer)(int _sock, char *PacketBuffer);
Мне хочется сделать так, что бы можно было в качестве параметра указывать любую созданную структуру. Например так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct s_Packet
{
    char msgBuffer[32];
};
 
void do_msg(int _sock, s_Packet msg) // в качестве параметра, используется наша новая структура
{
  std::cout << "\nmsg" << msg.msgBuffer;
}
 
int main()
{
  OriServer Server;
  Server.CreateServer(500);
  Server << "msg" << do_msg;
  Server.RunServer();
  return 0;
}
Возможно ли такое создать? Возможно это сделать именно в таком стиле, как показано в моём примере? Заранее спасибо.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.09.2014, 02:11
Ответы с готовыми решениями:

Вызов глобальной функции из объекта класса
Здравствуйте! Допустим, к примеру, имеется класс, который может хранить в себе адрес на функцию, а также метод который &quot;запустит&quot;...

Объявление класса, создание объекта и вызов функции-члена
Всем добрый день! Вот так я объявляю класс. typedef map&lt;string, double&gt; datablock; typedef map&lt;string, string&gt; groupvars;...

Вызов константной функции для неконстантного объекта класса
Доброго дня! Имея класс с двумя перегруженными на основании константности функциями членами, каким образом лучше и проще вызвать...

8
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
10.09.2014, 04:27
C++
1
Server << "msg" << do_msg;
В Server перегружен оператор << под указатель на функцию. Если там сделан вызов этой функции, то откуда она получает аргументы?
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
10.09.2014, 07:53
Это можно сделать разве что передачей указателя на буфер, в котором хранится экземпляр пользовательского типа данных. Только так классу сервера не нужно будет знать тип данных, который он принимает и передает функции - для него это будет просто массив байт, а пользовательская функция уже может его кастануть к чему угодно. Теоретически.
0
1 / 1 / 1
Регистрация: 28.04.2013
Сообщений: 35
10.09.2014, 14:33  [ТС]
Цитата Сообщение от alsav22 Посмотреть сообщение
Если там сделан вызов этой функции, то откуда она получает аргументы?
Если вам интересно как это работает, то вот отрывки кода:
C++
1
typedef void (* PacketFunc_Sock_Buffer)(int _sock, char *PacketBuffer);
C++
1
OriServer& operator << (PacketFunc_Sock_Buffer Func);
C++
1
2
3
4
5
6
7
8
9
10
OriServer& OriServer::operator << (PacketFunc_Sock_Buffer Func)
{
 strcpy(m_cmd_SBuf[this->IDServer].NamePack[m_cmd_SBuf[this->IDServer].count_cmd], this->Local_Cmd_Char_Buffer);
 
// Массив функций. По сути, тут идёт передача адреса функции. После она будет вызываться при необходимости.
 m_cmd_SBuf[this->IDServer].Buffer_Cmd_Sock_buffer[m_cmd_SBuf[this->IDServer].count_cmd] = Func;
 m_cmd_SBuf[this->IDServer].count_cmd++;
 
   return *this;
}
C++
1
2
3
    
// Вызов функции, здесь ответ на ваш вопрос. current_client, Packet->buffer есть те самые параметры
((*m_cmd_SBuf[IDServer].Buffer_Cmd_Sock_buffer[i])(current_client, Packet->buffer));
Добавлено через 49 минут
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
#include <stdio.h>
#include <iostream>
 
struct s_test
{
    int i;
    char buf[32];
};
 
typedef void (*TFUNC) (int sock);
#define void template <typename OriStruct> TFUNC
 
void msg(int sock, OriStruct Buffer)
{
  std::cout << Buffer.buf << " : " << sock << "\n";
}
 
int _tmain(int argc, _TCHAR* argv[])
{
     s_test my_test;
     my_test.i = 100;
     strcpy(my_test.buf, "Hello, World!");
     msg(10, my_test);
 
     std::system("PAUSE");
    return 0;
}
Вроде так)

Добавлено через 26 минут
Ну, для того что бы передать в функцию структуру, это работает нормально, а вот для перегрузки оператора, это ужасно
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
10.09.2014, 16:20
Орион, Вместо фунции передавай в свое API объект вот такой структуры.
C++
1
2
3
4
5
6
7
8
struct PacketHandler
{
    template <typename StructT>
    void operator()(int sock, StructT const & packet)
    {
        // do smth
    }
};
Т.е. будет так:
C++
1
2
3
4
  OriServer Server;
  Server.CreateServer(500);
  Server << "msg" << PacketHandler();
  Server.RunServer();
Внутри же будет вызываться operator() с нужным значением sock и произвольным packet.
Тоже не без ограничений решение (например на не типовые пакеты все равно придется писать специализации), но по крайней мере есть от чего отталкиваться.
0
1 / 1 / 1
Регистрация: 28.04.2013
Сообщений: 35
10.09.2014, 18:17  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
место фунции передавай в свое API объект вот такой структуры.
К сожалению хочется передавать функцию через оператор перегрузки, в которой будет аргумент в виде любой структуры.
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
10.09.2014, 18:24
Цитата Сообщение от Орион Посмотреть сообщение
К сожалению хочется передавать функцию через оператор перегрузки, в которой будет аргумент в виде любой структуры.
Указатель на шаблон передать нельзя, можно передать только указатель на конкретную истанцию, а это тоже самое что передать конкретную обычную функцию.
Поэтому остаются только динамические методы (общий базовый класс, все возможные структуры пакетов наследуются от него и определяют работу с данными в виртуальных методах, твоя функция же будет принимать указатель на этот базовый класс). Но у них тоже свои ограничения.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
10.09.2014, 19:09
Цитата Сообщение от Орион Посмотреть сообщение
хочется передавать функцию через оператор перегрузки, в которой будет аргумент в виде любой структуры
На вопрос так и не ответили:
Цитата Сообщение от alsav22 Посмотреть сообщение
Если там сделан вызов этой функции, то откуда она получает аргументы?
Вот этого не вижу в перегруженном операторе:
Цитата Сообщение от Орион Посмотреть сообщение
// Вызов функции, здесь ответ на ваш вопрос. current_client, Packet->buffer есть те самые параметры
C++
1
((*m_cmd_SBuf[IDServer].Buffer_Cmd_Sock_buffer[i])(current_client, Packet->buffer));
Где происходит вызов функции? Откуда берутся current_client, Packet?
0
1 / 1 / 1
Регистрация: 28.04.2013
Сообщений: 35
10.09.2014, 20:04  [ТС]
Цитата Сообщение от alsav22 Посмотреть сообщение
Где происходит вызов функции? Откуда берутся current_client, Packet?
Эта строчка и есть вызов функции.
C++
1
((*m_cmd_SBuf[IDServer].Buffer_Cmd_Sock_buffer[i])(current_client, Packet->buffer));
Всё это происходит в отдельном потоке и обрабатывается, если было получено сообщение.
Следовательно current_client - это сокет, который был передан потоку, при подключение клиента.
Packet - это структура-пакет. Она принимается сообщением от сервера. В ней есть буффер Packet->buffer, в нём сообщение так сказать.

m_cmd_SBuf[] - это структура, которая хранит в себе адрес функции, имя пакета, кол. во функций с данным типом аргументов (В нашем случае это Sock и Buffer).
m_cmd_SBuf[].Buffer_Cmd_Sock_buffer[] - это поле и содержит функцию, которую мы указали при перегрузке.

C++
1
Server << "msg" << do_msg;
Т.е в m_cmd_SBuf[].Buffer_Cmd_Sock_buffer[] функция do_msg с типом PacketFunc_Sock_Buffer, который в свою очередь является void (int, char *)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.09.2014, 20:04
Помогаю со студенческими работами здесь

Вызов метода класса из сторонней функции без объявления объекта
Собственно вопрос в топике. Можно? т.е. есть некий класс MyMySQLClass() в котором прописаны параметры доступа к БД, инициализация...

Реализовать описание метода класса с заданными параметрами
У меня такая проблема: У меня есть класс матриц, мне нужно описать метод(фунцию или процедуру), на вход которому подаются 4 значения, 2...

Вызов свойств объектов из массива или объекта с параметрами
Допустим у нас есть несколько объектов: $.Nav = { init: function(){ return this; }, ...

Вызов базового конструктора с параметрами из дочернего класса
Всем привет. Есть базовый класс, у которого есть конструктор с параметром. Создал дочерний класс без конструктора с параметром. Объявляю...

Преобразовать вызов метода класса с параметром в функцию с двумя параметрами
Можно ли при помощи адаптеров преобразовать выражение типа x-&gt;Func(y) в выражение Func(x,y)? Нужно для использования в list.sort()....


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru