【问题标题】:setTimeout like functionality for c++类似于 c++ 的 setTimeout 功能
【发布时间】:2026-01-05 16:40:02
【问题描述】:

我很想为 c++ 创建类似 javascript 的 setTimeoutsetInterval 功能(无需增强)。我想要实现的目标:一个基类,可以在重复或单次延迟后调用其子类成员变量。

我已经有一个update 函数和超时功能。我还找到了如何将成员函数指针传递给基类并使用以下方法触发该函数:

class BaseClass {
public:
     template <class object>
     void triggerNow(object *obj, void (object::*func)()) {
          ((obj)->*(func))();
     }

} 

class SubClass : public BaseClass {
public:
    void update() {
         triggerNow(this, &SubClass::worked)
    }
    void worked() {
         cout << "worked!";
    }
}

我目前面临的问题是如何将object *objvoid (object::*func)() 存储在向量(或其他容器)中。我只是想出模板...

如何将triggerNow 的两个模板化参数存储在一个向量中?一旦我弄清楚这一点,我就可以创建我的 setTimeout 和 setInterval!

【问题讨论】:

  • 你可以声明一个std::vector&lt;void (object::*)()&gt; theVector实例变量,然后看看Foundation的legendary NSTimer class是怎么做的(虽然那是Objective-C,C部分会匹配:)
  • @Ross:你的计时器要求有多难?您是否希望在此期间能够做其他事情? (即,多线程在发挥作用......)
  • 时间/定时器要求不是问题。

标签: c++ class timeout


【解决方案1】:

为了将 object* 和 object::*func 存储在向量中,您可以这样做:

struct Callable
{
  virtual ~Callable () {};
  virtual void operator()() = 0;
};

template <class Object>
struct TemplateCallable : public Callable
{
  typedef void (Object::*MemberFunction)();

  TemplateCallable(Object* obj, MemberFunction mem_fun)
     : _object(obj),
       _mem_fun(mem_fun)
  {}

  void operator() ()
  {
    _object->*_mem_fun();
  }

  Object* _obj;
  MemberFunction _mem_fun;
};

现在您可以将它们作为 Callable 存储在 std::vector 中,因为模板化版本是从 Callable 派生的。如果您将指针存储在 std::vector 中,但您需要记住在某些时候删除它们。

所以会得到这样的结果:

class TimerSomething
{
   template <class Object>
   void registerCallback (Object* obj, void (Object::*MemFun)())
   {
     _callbacks.push_back(new TemplatedCallback<Object>(obj, mem_fun));
   }

   void triggerAll ()
   {
     for (std::vector<Callable*>::iterator iter = _callbacks.begin();
          iter != _callbacks.end(); ++iter)
     {
       (**iter)();
     }
   }

   std::vector<Callable*> _callbacks;
};

【讨论】:

  • @MatthieuM。确实 std::function 或 boost::function 真的很有帮助。当 boost 和 C++11 都不可用时,一个人最终会编写大量代码 :)
  • 谢谢 试试这个!是的,boost 或 C++11 会有所帮助,但我正在寻找 vanilla c++ 解决方案。
  • virtual void operator() = 0; 的编译时错误为'operator()' cannot be the name of a variable or data member,但我添加了(因为想要更好的名称)virtual void doIt()=0。太棒了,谢谢!
  • @Ross 那是因为呼叫操作员实际上应该是virtual void operator() () = 0,我忘记了一对大括号,现在将修复。
【解决方案2】:

尚未对计时功能发表评论。

但是,由于您使用的是父类和基类,我建议使用多态性,而不是模板成员函数。

class BaseClass {
    public:
        virtual void triggerMe() = 0;

 };

class SubClass1 : public BaseClass {
    public:
        virtual void triggerMe()
        {
            //real code, do something
        }

 };

class SubClass2 : public BaseClass {
    public:
        virtual void triggerMe()
        {
            //real code, do something else
        }

 };

那么你就可以有一个vector 指向BaseClass 的指针:

vector<BaseClass*> objects;

objects.push_back(new SubClass1);
objects.push_back(new SubClass2);

for (auto it = objects.begin(); it != objects.end(); it++)
{
    it->triggerMe();
}

【讨论】:

  • 感谢您的回答。但是,如果我错了,请纠正我,这与拥有virtual void triggerMe()=0BaseClass 相比没有什么优势?
最近更新 更多