2016-05-15 35 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; 
}