Arrow
ArrowСәуір 30, 2017, 3 Т.Қ.

Callback функции

Callback функции, STL

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

Вот код:

ReverseString.h

#ifndef REVERSESTRING_H
#define REVERSESTRING_H

#include <map>
#include <string>
using namespace std;

class ReverseString
{
public:
    ReverseString();
    ~ReverseString();
    // Получить буквенный шифр и перекодировать в цифровой
    void decode(const string data);
    // Установка функции обратного вызова
    void setCallBackFunc(void (*func) (string data));

private:
    // Список численных значений для букв
    map<char, int> m_map;
    // Возвращаемая строка
    string m_string;
    // Указатель на функцию обратного вызова (возвращает цифровой шифр)
    void (*callbackfunction) (string data);
};

#endif // REVERSESTRING_H

ReverseString.cpp

#include "reversestring.h"

ReverseString::ReverseString()
{
    // Перевод букв (шеснадцатеричные значения) в десятичные
    m_map = {{'A', 10 }, {'B', 11}, {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
}

ReverseString::~ReverseString()
{
    // Очистить данные
    m_map.clear();
    m_string.clear();
}

void ReverseString::decode(const string data)
{
    // Получить буквенный шифр и перекодировать в цифровой
    m_string.clear();
    // Прекодировка
    for (int i = 0; i < m_string.length(); ++i) {
        m_string += m_map.at(data.at(i));
    }
    // Вызвать функцию обратного вызова для возврата
    // кодированной строки
    callbackfunction(m_string);
}

void ReverseString::setCallBackFunc(void (*func) (string data))
{
    // Установка функции обратного вызова
    callbackfunction = func;
}

main.cpp

#include <QCoreApplication>
#include <string>
#include <iostream>
using namespace std;

#include "reversestring.h"

void codeStringView(string data)
{
    // Вывести кодированную строку
    // полученную от callback функции
    cout << data << endl;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    string data;

    cout << "Enter string:" << endl;

    cin >> data;

    ReverseString *codeString = new ReverseString();

    // Установить функцию обратного вызова
    codeString->setCallBackFunc(codeStringView);

    codeString->decode(data);

    getchar();

    return a.exec();
}

Код написал от фонаря :) только для понимания как работает Callback функция.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

7
Evgenii Legotckoi
  • Мамыр 1, 2017, 2:06 Т.Ж.

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

Функция, которая передаётся в качестве CallBack функции должна быть статической. Не статические функции не получится передать в качестве обычных CallBack функций.

static void codeStringView(string data)
{
    // Вывести кодированную строку
    // полученную от callback функции
    cout << data << endl;
}
    Arrow
    • Мамыр 2, 2017, 4:35 Т.Ж.

    Программа запускается но результат не выводит. После ввода символа (А, В, С ... ) и нажатия Enter каретка переходит на новую строку и ничего не происходит. Нет ни ответа ни ошибки.

      Arrow
      • Мамыр 2, 2017, 4:37 Т.Ж.

      Она просто продолжает работать - реагирует на все нажатия клавиш.

        Evgenii Legotckoi
        • Мамыр 2, 2017, 11:18 Т.Ж.

        А дело оказалось вовсе не CallBack. Ошибка в следующем коде:

        Было

        for (int i = 0; i < m_string.length(); ++i) {
            m_string += m_map.at(data.at(i));
        }

        Стало

        for (int i = 0; i < data.length(); ++i) {
            m_string.append(to_string(m_map.at(data.at(i))));
        }

        Ошибки следующие:

        1. Проверка длины не той переменной. m_string.length() всегда будет равен нулю. Вы же его очищаете перед циклом.
        2. Добавлять к str::string нужно именно std::string. При попытке добавления данных переменной целочисленного типа - эта переменная воспринимается как код символа, а не как число 10, например.
        3. Поэтому нужно делать преобразование кода через std::to_string()
          Arrow
          • Мамыр 2, 2017, 1:13 Т.Қ.

          Спасибо!

          Концентрировал внимание на CallBack и понадеялся, что все остальное написал правильно. :)

          Теперь программа вылетает и пишет ошибку:

          Запускается C:\Users\admin\Desktop\CallBackFunc\bild\Debug\debug\CallBackFunc.exe... Error - RtlWerpReportException failed with status code :-1073741823. Will try to launch the process directly C:\Users\admin\Desktop\CallBackFunc\bild\Debug\debug\CallBackFunc.exe завершился с кодом -1073741819

          По отладчику вылетает на строке:

          callbackfunction(m_string);

          С сообщением: Segmentation fault.

            Evgenii Legotckoi
            • Мамыр 2, 2017, 1:18 Т.Қ.
            • Жауап шешім ретінде белгіленді.

            Ну как бы странно, что вылетает с Segmentation fault. Вот мой код.

            main.cpp
            #include <QCoreApplication>
            #include <string>
            #include <iostream>
            #include <QDebug>
            
            using namespace std;
            
            #include "reversestring.h"
            
            void codeStringView(string data)
            {
                // Вывести кодированную строку
                // полученную от callback функции
                cout << data << endl;
            }
            
            int main(int argc, char *argv[])
            {
                QCoreApplication a(argc, argv);
            
                string data;
            
                cout << "Enter string:" << endl;
            
                cin >> data;
            
                ReverseString *codeString = new ReverseString();
            
                // Установить функцию обратного вызова
                codeString->setCallBackFunc(codeStringView);
            
                codeString->decode(data);
            
                getchar();
            
                return a.exec();
            }
            reversestring.h
            #ifndef REVERSESTRING_H
            #define REVERSESTRING_H
            
            #include <map>
            #include <string>
            using namespace std;
            
            class ReverseString
            {
            public:
                ReverseString();
                ~ReverseString();
                // Получить буквенный шифр и перекодировать в цифровой
                void decode(const string data);
                // Установка функции обратного вызова
                void setCallBackFunc(void (*func) (string data));
            
            private:
                // Список численных значений для букв
                map<char, int> m_map;
                // Возвращаемая строка
                string m_string;
                // Указатель на функцию обратного вызова (возвращает цифровой шифр)
                void (*callbackfunction) (string data);
            };
            
            #endif // REVERSESTRING_H
            reversestring.cpp
            #include "reversestring.h"
            
            ReverseString::ReverseString()
            {
                // Перевод букв (шеснадцатеричные значения) в десятичные
                m_map = {{'A', 10 }, {'B', 11}, {'C', 12}, {'D', 13}, {'E', 14}, {'F', 15}};
            }
            
            ReverseString::~ReverseString()
            {
                // Очистить данные
                m_map.clear();
                m_string.clear();
            }
            
            void ReverseString::decode(const string data)
            {
                // Получить буквенный шифр и перекодировать в цифровой
                m_string.clear();
                // Прекодировка
                for (int i = 0; i < data.length(); ++i) {
                    m_string.append(to_string(m_map.at(data.at(i))));
                }
                // Вызвать функцию обратного вызова для возврата
                // кодированной строки
                callbackfunction(m_string);
            }
            
            void ReverseString::setCallBackFunc(void (*func) (string data))
            {
                // Установка функции обратного вызова
                callbackfunction = func;
            }
              Arrow
              • Мамыр 2, 2017, 1:29 Т.Қ.

              Понял, спасибо!

              Вылетало потому, что было так:

              codeString->decode(data);
              codeString->setCallBackFunc(codeStringView);

              А нужно так:

              codeString->setCallBackFunc(codeStringView);
              codeString->decode(data);

              Туплю.

                Пікірлер

                Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                Кіріңіз немесе Тіркеліңіз
                Г

                C++ - Тест 001. Первая программа и типы данных

                • Нәтиже:66ұпай,
                • Бағалау ұпайлары-1
                t

                C++ - Тест 001. Первая программа и типы данных

                • Нәтиже:33ұпай,
                • Бағалау ұпайлары-10
                t

                Qt - Тест 001. Сигналы и слоты

                • Нәтиже:52ұпай,
                • Бағалау ұпайлары-4
                Соңғы пікірлер
                G
                GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
                Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
                d
                dblas5Шілде 5, 2024, 11:02 Т.Ж.
                QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                k
                kmssrАқп. 8, 2024, 6:43 Т.Қ.
                Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                АК
                Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
                Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                Енді форумда талқылаңыз
                Evgenii Legotckoi
                Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
                добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                F
                FynjyШілде 22, 2024, 4:15 Т.Ж.
                при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
                BlinCT
                BlinCTМаусым 25, 2024, 1 Т.Ж.
                Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
                BlinCT
                BlinCTМамыр 5, 2024, 5:46 Т.Ж.
                Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
                Evgenii Legotckoi
                Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
                Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

                Бізді әлеуметтік желілерде бақылаңыз