簡體   English   中英

C ++信號回調(如javascript)

[英]C++ signal callback (like javascript)

我是C ++的新手,並且在學習新語言的同時嘗試移植一些JavaScript腳本。

我正在嘗試找到使用像javascript這樣的回調的解決方案,尤其是像js-signals庫這樣的回調

以下是javascript中的腳本。 可以將其轉換為C ++嗎? 怎么樣? 如果沒有,什么是最佳解決方案?

使用Javascript

var ns = {
   _callback: null,
   setUpdate: function(callback) {
      ns._callback = callback;
   },
  update: function() {
      // do some default things
      ns._callback();
   }
};
ns.setUpdate(function() {
   console.log("I'm Changed"); // will be: std::cout << "I'm Changed\n";
});

C ++

namespace ns {
   // ??
};
// ns::setUpdate(??);

您可以使用函數指針,如下所示:

#include <cstdio>
namespace ns {
  // defines a type named Callback that is a pointer
  // to a function that takes void and returns void
  typedef void (*Callback)();
  Callback _callback;

  void setUpdate( Callback cb) {
    _callback = cb;
  }
  void update() {
    _callback();
  }
}

void MyUpdate() {
  printf("hello from callback\n");
}

int main(int argc, char* argv[]) {

  ns::setUpdate(MyUpdate);
  ns::update();
}

輸出:

你好從回調

另請參見: Typedef函數指針?

我不會使用這樣的namespace 一個class可能更適合這樣的事情:

#include <iostream>
#include <functional>

class MyThing
{
public:
    MyThing() {}
    MyThing(const std::function<void()>& callback) : callback_(callback) {}
    void setUpdate(const std::function<void()>& callback)
    {
        callback_ = callback;
    }

    void update()
    {
        std::cout << "Update called\n";
        if (callback_) {
            callback_();
        }
    }
private:
    std::function<void()> callback_;
};

int main()
{
    MyThing my_thing1; // callback_ is initially unset in this object
    my_thing1.update(); // no callback is called
    my_thing1.setUpdate([](){ std::cout << "I'm Changed 1\n"; });
    my_thing1.update(); // calls the lambda set in the previous line
    MyThing my_thing2([](){ std::cout << "I'm Changed 2\n"; });
    my_thing2.update(); // calls the lambda in the prevous line
}

這將輸出

更新稱為
更新稱為
我變了1
更新稱為
我變了2

這是將javascript js信號庫移植到c ++的好方法:

#include <string>
#include <map>
#include <functional>

// You only need this Signal class
class Signal {

    // store all callbacks to a string map
    std::map<std::string, std::function<void()>> callbacks;

    // check if callback already exists. optional
    bool exists(std::string key) {
        if (callbacks.find(key) == callbacks.end()) {return false;}
        else {return true;}
    }

    public:
    void add(std::string key, std::function<void()> cb) {
        if (!exists(key)) {remove(key);}
        callbacks.insert(std::pair<std::string, std::function<void()>>(key, cb));
    }
    void remove(std::string key) {
        callbacks.erase(key);
    }
    void dispatch() {
        for (std::map<std::string, std::function<void()>>::iterator it = callbacks.begin(); it != callbacks.end(); it++) {
            callbacks[it->first]();
        }
    }

    // this destroys the signal
    void dispose() {
        callbacks.clear();
    }
};

int main() {
    // create a signal
    Signal* onFire = new Signal();

    // add some callbacks
    int a_variable = 10;
    onFire->add("a_sound_is_heard", [&]() {
        // some code when onFire.dispatch() happens
        std::cout << "i can use this variable too :) " << a_variable << std::endl;
        // you can also use the onFire variable
    });
    onFire->add("a_bullet_appears", [&]() {
        // some code again
    });

    // remove some callbacks (add a silencer for your gun)
    onFire->remove("a_sound_is_heard");

    // whenever you want, execute the event
    onFire->dispatch();

    // don't forget to delete the signal from memory
    onFire->dispose();
    delete onFire;

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM