LINUX.ORG.RU

Вызов по указателю метода структуры вложенной в класс

 


0

1

Приветствую.

Имеется класс вида

class CQueue
{
private:
    struct cmd_t {
        int8_t pri;
        std::string id, msg;
        void (CQueue::*handle)(const std::string & id, const std::string & msg);
    };
....
public:
    void handle_...(const std::string & id, const std::string & msg);
    void handle_push(const std::string & id, const std::string & msg);

int Put(const std::string & id, const std::string & msg, void (CQueue::*handle)(const std::string & id, const std::string & msg), const int8_t pri = 0);
void Handler(void);

из метода не этого класса добавляю в эту очередь и GCC не возмущается как

pQ->Put(id, std::string(msg, msgLen), &CQueue::handle_push);

а как теперь обратиться к этому методу внутри этого же класса??? думал должно быть что то вроде

void CQueue::Handler(void)
{
.....
    cmd_t cmd;
    while (Get(cmd))
        if (cmd.handle)
            (cmd.*handle)(cmd.id, cmd.msg);

но компилятор против, говорит нет никакого handle

так тоже пробовал и тут типы не совпадают

(cmd.*cmd.handle)(cmd.id, cmd.msg)

или вообще все это не правильно и надо городить на std::function ???

★★★

Последнее исправление: wolverin (всего исправлений: 1)

(cmd.*handle)(cmd.id, cmd.msg);

Вы неправильно используете указатель на функцию. Имя функции - это и есть её адрес. Вы же не пишете, например, вызов printf() как *prtinf()?

raspopov
()

void (CQueue::*handle)(const std::string & id, const std::string & msg);

убери CQueue:: в декларации handle, это какой-то невменяемый треш. Я даже сходу не пойму что таким образом объявлено. если убрать CQueue - будет указатель на функцию.

должно быть

void (*handle)(const std::string & id, const std::string & msg);
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
 void (CQueue::*handle)(const std::string & id, const std::string & msg);

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

a ты в своем коде вызываешь его от обьекта класса cmd_t:

cmd_t cmd;
while (Get(cmd))
    if (cmd.handle)
        (cmd.*handle)(cmd.id, cmd.msg);
alysnix ★★★
()
Ответ на: комментарий от wolverin

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

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

alysnix ★★★
()
Ответ на: комментарий от dvetutnev

указатель на метод класса исключительно тема из плюсов ))

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

wolverin ★★★
() автор топика
Ответ на: комментарий от alysnix

я только не понял где он это написал.

Возможно, строчка под последним сообщением на странице вида «Показано 8 сообщений из 10. Показать все.» даст ответ на этот вопрос 🤣. Например, кто-то из вас внес другого в ЧС.

Virtuos86 ★★★★★
()
Ответ на: комментарий от alysnix

так вспомнил. это указатель на функцию член класса. гы.

Позор на мои седины. Я тоже забыл про бинарные операторы .* и ->*. Использовал их, наверное, только раз за 25 лет.. 🤦‍♂️

raspopov
()
Ответ на: комментарий от wolverin

интересно, разве для любой архитектуры?

«Отметим также, что хотя приведенные цифры, строго говоря, относятся только к современным процессорам x86/x64, ожидается, что аналогичные закономерности относительной стоимости операций будут наблюдаться и на других современных процессорах с большим многоуровневым кэшем (например, ARM Cortex A или SPARC); с другой стороны, MCU (включая ARM Cortex M) достаточно разнообразны, поэтому некоторые закономерности могут быть там иными.» (Источник)

У вас какой ЦП?

это типа что if быстрее обращения по указателю?

Это типа что косвенный вызов вручную и вызов по виртуальной таблице в общем случае аналогичны. А вот удобство второго и для программиста, и для компилятора гораздо выше.

raspopov
()
Ответ на: комментарий от raspopov

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

wolverin ★★★
() автор топика