2016-05-15 27 views
0

我是C++的新手,我试图在学习新语言的同时移植一些javascipt脚本。C++信号回调(如javascript)

我试图找到解决使用回调像JavaScript,尤其喜欢js-signals

下面是javascipt的脚本。它可以转换为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(??); 
+0

是的,你可以在C++中做回调。我认为最接近您的JS代码的C++(我不知道JS的所有内容,所以我只是猜测)会将lambda存储在'std :: function'成员变量中。 – MikeMB

+1

搜索“函数指针C++”和“lambda表达式C++”....这会让你开始.....有很多处理,虽然 – DarthRubik

回答

2

您可以使用函数poi NTER,像这样:

#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 function pointer?

+0

非常感谢。你能解释一下这是什么吗? “typedef void(* Callback)();” – Liakos

+0

为代码添加了一条评论来解释..我在原始文章中的链接也解释了更多。 –

1

我不会用一个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

0

这是一个很好的方式来港的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; 
}