Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Передача указателя на член функции объекта в функцию для глобальных обработчиков: решение в MSVC2010

Delphi , Синтаксис , Память и Указатели

Вопрос, с которым вы столкнулись, заключается в передаче указателя на член функции объекта в функцию, ожидающую глобальный указатель на функцию. В вашем случае есть динамический список объектов, для каждого из которых необходимо передать функцию-обработчик. В C# это решается с помощью делегатов, но в C++ аналогичного механизма нет в стандартной библиотеке для версий компиляторов, предшествующих C++11.

Для решения вашей задачи можно использовать следующий подход:

  1. Создать вспомогательную функцию, которая будет принимать указатель на объект и указатель на член-функцию, которую нужно выполнить.
  2. Использовать эту вспомогательную функцию для создания "обертки" вокруг члена-функции, которая может быть передана в функцию, ожидающую глобальный указатель на функцию.

Вот пример кода, который демонстрирует данный подход:

#include <iostream>
#include <list>
#include <functional>

// Определение класса с виртуальной функцией-обработчиком
class BaseTask {
public:
    virtual void task(float x, float y) = 0;
};

// Реализация класса, наследующегося от BaseTask
class ListeningTask : public BaseTask {
public:
    void task(float x, float y) override {
        std::cout << "Обработчик объекта: " << this << ", параметры: " << x << ", " << y << std::endl;
    }
};

// Вспомогательная функция для создания обертки вокруг члена-функции
void taskWrapper(BaseTask* task, float x, float y) {
    task->task(x, y);
}

// Класс, который будет использоваться для подписки на обработчики
class RegisterTask {
public:
    void subscribe(std::function<void(float, float)> callback) {
        callback(1.0f, 2.0f);
    }
};

// Главная функция
int main() {
    RegisterTask registerTask;
    std::list<ListeningTask> listeningTasks;

    // Создание списка объектов
    for (int i = 0; i < 10; ++i) {
        listeningTasks.push_back(ListeningTask());
    }

    // Создание оберток для каждого обработчика
    for (auto& task : listeningTasks) {
        std::function<void(float, float)> callback = std::bind(taskWrapper, &task, std::placeholders::_1, std::placeholders::_2);
        registerTask.subscribe(callback);
    }

    return 0;
}

В данном примере мы создаем вспомогательную функцию taskWrapper, которая принимает указатель на объект BaseTask и вызывает его метод task. Затем, используя функтор std::bind, мы создаем обертку вокруг этого метода для каждого объекта в списке listeningTasks. Полученные обертки передаются в функцию subscribe класса RegisterTask.

Обратите внимание, что для работы данного примера требуется поддержка std::function и std::bind, которые присутствуют в Visual Studio 2010, но могут быть использованы в namespace tr1 вместо std.

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

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Память и Указатели ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-08-30 18:46:02/0.005234956741333/1