Как я могу использовать статический метод C ++ в качестве обратного вызова для таймера Poco? - PullRequest
0 голосов
/ 02 сентября 2018

В частности, я говорю о конструкторе этого класса Poco: Poco.TimerCallback

Я хотел бы использовать его в унаследованном коде C ++, где большинство написанных мною классов являются «статическими», так что они содержат только статические методы и не содержат конструкторов, просто потому, что мне все равно не понадобится несколько экземпляров таких объектов и классы просто для инкапсуляции. Ну да, ребята из Poco предлагают добавить метод обратного вызова, подобный этому:

TimerCallback<MyClass> callback(*this, &MyClass::onTimer);
timer.start(callback);

Правильно ли я понимаю этот фрагмент кода: MyClass::onTimer также может быть статическим методом MyClass, но мне также нужен текущий экземпляр MyClass, так что методы статических классов, которые не создаются, являются просто запрещено использовать как TimerCallback, или я ошибаюсь?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

После столкновения с гораздо более неприятной проблемой (связанной с указателями на членов класса) при расширении TimerTaskAdapter кто-то предложил извлечь мой класс непосредственно из TimerTask: Указатель на тип члена, несовместимый с типом объекта → Что это причина?

См. Этот исходный код:

ProceduralTimerTaskAdapter.h:

// Header file for ProceduralTimerTaskAdapter.cpp class file.
// This is an extension of the Poco::Util::TimerTask class.

#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>

#ifndef PROCEDURALTIMERTASKADAPTER_H
#define PROCEDURALTIMERTASKADAPTER_H

using namespace std;
using namespace Poco::Util;

typedef void (*Callback) (TimerTask&);

namespace Poco {
  namespace Util {
    class ProceduralTimerTaskAdapter : public TimerTask {
    public:
      ProceduralTimerTaskAdapter (Callback procedure); // Constructor

      void run (); // Method defining the main thread
    protected:
      ~ProceduralTimerTaskAdapter (); // Destructor (not for general use)
    private:
      ProceduralTimerTaskAdapter (); // Default constructor (not for general use)

      Callback procedure; // The callback procedure called by the timer.
    };
  }
}

#endif

ProceduralTimerTaskAdapter.cpp:

// This is the implementation of the ProceduralTimerTaskAdapter class.

#include <iostream>
#include <Poco/Util/Timer.h>
#include <Poco/Util/TimerTask.h>
#include "ProceduralTimerTaskAdapter.h"

using namespace std;
using namespace Poco::Util;

ProceduralTimerTaskAdapter::ProceduralTimerTaskAdapter (Callback proc) :
  TimerTask::TimerTask (),
  procedure (proc)
{
}

ProceduralTimerTaskAdapter::~ProceduralTimerTaskAdapter ()
{
}

void ProceduralTimerTaskAdapter::run ()
{
  procedure (*this);
}

Сработало из коробки. Тем не менее, спасибо за ваши ответы и комментарии!

0 голосов
/ 03 сентября 2018

Я бы не назвал это «забаненным» - функции обратного вызова просто не реализованы, и ничто не мешает вам реализовать это самостоятельно (и отправить его обратно в качестве вклада, если вы склонны это сделать).

Я бы просто расширил TimerTaskAdapter , чтобы он не требовал экземпляра объекта, например. как то так:

typedef void (*FunctionCallback)(TimerTask&);
TimerTaskAdapter(FunctionCallback func): _pObject(0), _method(0), _func(func){}
...
FunctionCallback _func;

Затем определите в TimerTaskAdapter::run(), что является нулем и нужно ли вызывать метод или функцию:

void run()
{
    if (_pObject) (_pObject->*_method)(*this);
    else (*_func)(*this);
}
...