2013-09-06 6 views
14

सी ++ सीखना और कुछ पैटर्न से परिचित होने की कोशिश कर रहा है। signals2 doc में स्पष्ट रूप से स्लॉट्स और सिग्नल के साथ कई चीजें हैं जो मैं कर सकता हूं। मुझे समझ में नहीं आता कि किस प्रकार के अनुप्रयोग (मामलों का उपयोग करें) मुझे इसके लिए उपयोग करना चाहिए।बूस्ट सिग्नल 2 का उपयोग कैसे और क्यों करेगा?

मैं एक राज्य मशीन प्रेषण परिवर्तन घटनाओं की रेखाओं के साथ सोच रहा हूं। गतिशील रूप से टाइप की गई पृष्ठभूमि (सी #, जावा इत्यादि) से आ रहा है, आप एक इवेंट डिस्पैचर या एक स्थिर रेफरी या कॉलबैक का उपयोग करेंगे।

क्या क्रॉस-क्लास कॉलबैक का उपयोग करने के साथ सी ++ में कठिनाइयां हैं? क्या यह अनिवार्य रूप से है क्यों संकेत 2 मौजूद है?

उदाहरण मामलों में से एक दस्तावेज़/दृश्य है। यह पैटर्न कहां से बेहतर अनुकूल है, कार्यों के वेक्टर का उपयोग करके और प्रत्येक को लूप में कॉल करना, या एक लैम्ब्डा कहें जो पंजीकृत श्रवण वर्ग के उदाहरणों में राज्य परिवर्तन को कॉल करता है?

class Document 
{ 
public: 
    typedef boost::signals2::signal<void()> signal_t; 

public: 
    Document() 
    {} 

    /* Connect a slot to the signal which will be emitted whenever 
     text is appended to the document. */ 
    boost::signals2::connection connect(const signal_t::slot_type &subscriber) 
    { 
     return m_sig.connect(subscriber); 
    } 

    void append(const char* s) 
    { 
     m_text += s; 
     m_sig(); 
    } 

    const std::string& getText() const 
    { 
     return m_text; 
    } 

private: 
    signal_t m_sig; 
    std::string m_text; 
}; 

और

class TextView 
{ 
public: 
    TextView(Document& doc): m_document(doc) 
    { 
     m_connection = m_document.connect(boost::bind(&TextView::refresh, this)); 
    } 

    ~TextView() 
    { 
     m_connection.disconnect(); 
    } 

    void refresh() const 
    { 
     std::cout << "TextView: " << m_document.getText() << std::endl; 
    } 
private: 
    Document&    m_document; 
    boost::signals2::connection m_connection; 
}; 
+2

एक बात के लिए, ** boost.signals2 ** हमारे पास लैम्बास होने से पहले बनाया गया था। हां, अब यह 'वेक्टर <फ़ंक्शन >', और उसके बाद 'push_back() 'lambdas होने के बराबर है। आप कुछ सुविधाएं चाहते हैं, जैसे कि कॉलबैक के उचित क्रम, सिग्नल स्लॉट डिस्कनेक्शन, दोनों ओर से, संकेतों को निलंबित करना आदि; वह तब होगा जब आपको कुछ रैपर की आवश्यकता होगी (जो आश्चर्यजनक रूप से सरल हैं, [यह मैंने लिखा है] (https://bitbucket.org/danielko/simplesignal/src/6557131d489f3d810a39fd4a2f0401bb0dab1922/include/SimpleSignal%2B%2B.hpp?at=default))। – DanielKO

उत्तर

21

Boost.Signals2 बस "कॉलबैक की एक सरणी" नहीं है, यह अतिरिक्त मूल्य का एक बहुत है। IMO, सबसे महत्वपूर्ण बिंदु हैं:

  1. थ्रेड-सुरक्षा: कई धागे कनेक्ट हो सकता है/डिस्कनेक्ट/समवर्ती एक ही संकेत आह्वान, दौड़ की स्थिति को शुरू करने के बिना। यह विशेष रूप से तब उपयोगी होता है जब एक एसिंक्रोनस सबसिस्टम से संचार होता है, जैसे सक्रिय ऑब्जेक्ट अपने धागे में चल रहा है।
  2. connection और scoped_connection हैंडल जो signal तक सीधे पहुंच के बिना डिस्कनेक्शन की अनुमति देते हैं। ध्यान दें कि boost::function (या std::function) जैसे अतुलनीय स्लॉट डिस्कनेक्ट करने का यही एकमात्र तरीका है।
  3. अस्थायी स्लॉट अवरोधन। एक सुनवाई मॉड्यूल अस्थायी रूप से अक्षम करने के लिए एक साफ तरीका प्रदान करता है (उदाहरण के लिए जब कोई उपयोगकर्ता दृश्य में संदेश प्राप्त करने का अनुरोध करता है)।
  4. स्वचालित स्लॉट जीवनकाल ट्रैकिंग: एक सिग्नल स्वचालित रूप से "कालबाह्य" स्लॉट से डिस्कनेक्ट हो जाता है। स्थिति पर विचार करें जब एक स्लॉट एक बांधने की मशीन एक गैर copyable वस्तु shared_ptr रों द्वारा प्रबंधित को संदर्भित करती है:

    shared_ptr<listener> l = listener::create(); 
    auto slot = bind(&listener::listen, l.get()); // we don't want aSignal_ to affect `listener` lifespan 
    aSignal_.connect(your_signal_type::slot_type(slot).track(l)); // but do want to disconnect automatically when it gets destroyed 
    

निश्चित रूप से, एक सब से ऊपर कार्यक्षमता अपने दम पर फिर से लागू कर सकते हैं "कार्यों का एक वेक्टर का उपयोग कर और प्रत्येक को लूप में कॉल करना "आदि, लेकिन सवाल यह है कि यह Boost.Signals2 से बेहतर कैसे होगा। पहिया का पुन: आविष्कार शायद ही कभी एक अच्छा विचार है।

+0

मुझे लगता है कि एक अतिरिक्त चीज जिसे मैं समझ नहीं पा रहा हूं वह है। यह मुझे संकलित करने के लिए वास्तव में विचित्र (मेरे लिए) करने के लिए मजबूर किया। क्या बिना किसी प्रतिबंध के स्पष्ट रूप से संकेतों का उपयोग करने का कोई तरीका है? – FlavorScape

+3

@ फ्लेवरस्केप क्या मतलब है "कॉन्स आवश्यकता"? स्लॉट कॉन्स्ट संदर्भ द्वारा स्वीकार किए जाते हैं, क्योंकि उनकी प्रतिलिपि बनाई जाती है। लेकिन फिर, आप 'std :: ref' द्वारा लिपटे पैरामीटर सहित, जो कुछ भी आप चाहते हैं, उसके भीतर' बाध्य 'कर सकते हैं। –

+0

+1 के लिए +1 यह बताएं कि यह ** अतुलनीय ** स्लॉट्स को डिस्कनेक्ट करने का एकमात्र तरीका है, जैसे boost :: function (या std :: function) _ - इसे सरल शब्दों में डालना: जब तक कोई सादे वेनिला ** फ़ंक्शन पॉइंटर्स का उपयोग नहीं करता * *, सिग्नल –

संबंधित मुद्दे