Как вызвать функцию из любого класса по указателю на него?

0

Я строю двигатель. Мне нужно создать класс Timer который вызовет функцию указателем из отдельного класса. Например:

class MyTimer {
public:
    void setTimeoutFunction( _pointer_, unsigned short timeoutMs ) {
        // here we need to have a opportunity to store a _pointer_ to a function
    }
    void tickTimer() {
        ...
        // here I need to call a function by a pointer
        ...
    }
};

// Main class:
class MyAnyClass {
public:
    void start() {
        MyTimer myTimer;
        myTimer.setTimeoutFunction( startThisFunc, 1500 ); // 1500ms = 1.5s
        while ( true ) {
            myTimer.tickTimer();
        }
    }
    void startThisFunc() { ... }
}

В суммировании, как вы храните указатель на функцию, принадлежащую некоторому классу, и вызываете эту функцию указателем?

  • 0
    Этот вопрос слишком широкий, чтобы получить хороший ответ, но, возможно, вам стоит начать с std :: function, с помощью которой вы можете архивировать то, что хотите.
  • 0
    Будет ли у вас всегда один частный таймер только для одного объекта за раз, или один объект таймера должен быть в состоянии обрабатывать несколько объектов разных типов?
Показать ещё 1 комментарий
Теги:
pointers
design-patterns

2 ответа

1
Лучший ответ

Для ваших требований я бы рекомендовал сделать таймер шаблоном класса:

template <typename T>
struct MyTimer
{
    using FuncPtr = void (T::*)();

    MyTimer(FuncPtr ptr, T * obj, unsigned int timeout_ms)
    : ptr_(ptr), obj_(obj), timeout_ms_(timeout_ms) {}

    void tickTimer()
    {
        (obj_->*ptr_)();
    }

    FuncPtr ptr_;
    T * obj_;
    unsigned int timeout_ms_;
};

Применение:

struct MyAnyClass
{
    void start()
    {
        MyTimer<MyAnyClass> myTimer(&MyAnyClass::startThisFunc, this, 1500);
        while (true) { myTimer.tickTimer(); }
    }

    void startThisFunc() { /* ... */ }
};
  • 0
    Вау, это крутой трюк. Спасибо! Можно ли как-то использовать этот пример без ключевого слова using? Я думаю, что это стиль C ++ 11, но, к сожалению, в настоящее время я не могу использовать C ++ 11.
  • 0
    Здесь: en.cppreference.com/w/cpp/language/type_alias я нашел образец: using func = void (*) (int,int); - псевдоним типа, идентичный typedef void (*func)(int, int); Я думаю, это то, что мне нужно :)
0

В С++ 11 вы можете использовать std :: function. Хорошее руководство по его использованию находится здесь: http://en.cppreference.com/w/cpp/utility/functional/function

Я создал новый фрагмент кода, содержащий только тот случай, который вы хотите.

#include <stdio.h>
#include <functional>
#include <iostream>

struct Foo {
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_+i << '\n'; }
    int num_;
};


int main()
{
  // store a call to a member function
    std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
    const Foo foo(314159);
    f_add_display(foo, 1);

    return 0;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню