Arrow
Arrow30 квітня 2017 р. 15:00

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
  • 01 травня 2017 р. 02:06

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

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

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

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

      Arrow
      • 02 травня 2017 р. 04:37

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

        Evgenii Legotckoi
        • 02 травня 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
          • 02 травня 2017 р. 13: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
            • 02 травня 2017 р. 13: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
              • 02 травня 2017 р. 13:29

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

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

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

              А нужно так:

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

              Туплю.

                Коментарі

                Only authorized users can post comments.
                Please, Log in or Sign up
                AD

                C++ - Тест 004. Указатели, Массивы и Циклы

                • Результат:50бали,
                • Рейтинг балів-4
                m
                • molni99
                • 26 жовтня 2024 р. 08:37

                C++ - Тест 004. Указатели, Массивы и Циклы

                • Результат:80бали,
                • Рейтинг балів4
                m
                • molni99
                • 26 жовтня 2024 р. 08:29

                C++ - Тест 004. Указатели, Массивы и Циклы

                • Результат:20бали,
                • Рейтинг балів-10
                Останні коментарі
                ИМ
                Игорь Максимов22 листопада 2024 р. 19:51
                Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                Evgenii Legotckoi
                Evgenii Legotckoi31 жовтня 2024 р. 21:37
                Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                A
                ALO1ZE19 жовтня 2024 р. 15:19
                Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                ИМ
                Игорь Максимов05 жовтня 2024 р. 14:51
                Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                d
                dblas505 липня 2024 р. 18:02
                QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                Тепер обговоріть на форумі
                Evgenii Legotckoi
                Evgenii Legotckoi24 червня 2024 р. 22:11
                добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                t
                tonypeachey115 листопада 2024 р. 14:04
                google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                NSProject
                NSProject04 червня 2022 р. 10:49
                Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                9
                9Anonim25 жовтня 2024 р. 16:10
                Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                Слідкуйте за нами в соціальних мережах