Arrow
ArrowApril 30, 2017, 3 p.m.

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 функция.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

7
Evgenii Legotckoi
  • May 1, 2017, 2:06 a.m.

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

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

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

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

      Arrow
      • May 2, 2017, 4:37 a.m.

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

        Evgenii Legotckoi
        • May 2, 2017, 11:18 a.m.

        А дело оказалось вовсе не 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
          • May 2, 2017, 1:13 p.m.

          Спасибо!

          Концентрировал внимание на 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
            • May 2, 2017, 1:18 p.m.
            • The answer was marked as a solution.

            Ну как бы странно, что вылетает с 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
              • May 2, 2017, 1:29 p.m.

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

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

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

              А нужно так:

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

              Туплю.

                Comments

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

                C ++ - Test 004. Pointers, Arrays and Loops

                • Result:50points,
                • Rating points-4
                m

                C ++ - Test 004. Pointers, Arrays and Loops

                • Result:80points,
                • Rating points4
                m

                C ++ - Test 004. Pointers, Arrays and Loops

                • Result:20points,
                • Rating points-10
                Last comments
                Evgenii Legotckoi
                Evgenii LegotckoiOct. 31, 2024, 9:37 p.m.
                Django - Lesson 064. How to write a Python Markdown extension Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                A
                ALO1ZEOct. 19, 2024, 3:19 p.m.
                Fb3 file reader on Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                ИМ
                Игорь МаксимовOct. 5, 2024, 2:51 p.m.
                Django - Lesson 064. How to write a Python Markdown extension Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                d
                dblas5July 5, 2024, 6:02 p.m.
                QML - Lesson 016. SQLite database and the working with it in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                k
                kmssrFeb. 9, 2024, 2:43 a.m.
                Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                Now discuss on the forum
                Evgenii Legotckoi
                Evgenii LegotckoiJune 24, 2024, 10:11 p.m.
                добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                t
                tonypeachey1Nov. 15, 2024, 2:04 p.m.
                google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                NSProject
                NSProjectJune 4, 2022, 10:49 a.m.
                Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                9
                9AnonimOct. 25, 2024, 4:10 p.m.
                Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                Follow us in social networks