2009-07-22 18 views
7

इसलिए मैंने क्यूटी 4.5 सीखना शुरू कर दिया है और सिग्नल/स्लॉट तंत्र को सहायता के लिए पाया है। हालांकि, अब मैं खुद को दो प्रकार के वास्तुकला पर विचार करने के लिए पाता हूं।सिग्नल/स्लॉट बनाम प्रत्यक्ष फ़ंक्शन कॉल

यह एक मैं प्रयोग करेंगे

class IDataBlock 
{ 
    public: 
    virtual void updateBlock(std::string& someData) = 0; 
} 

class Updater 
{ 

    private: 
    void updateData(IDataBlock &someblock) 
    { 
     .... 
     someblock.updateBlock(data); 
      .... 
    } 
} 

नोट है: संक्षिप्तता के लिए inlined कोड।

संकेतों के साथ

अब मैं कर सकता बस

void Updater::updateData() 
{ 
    ... 
    emit updatedData(data); 
} 

यह क्लीनर है, एक अंतरफलक की आवश्यकता कम कर देता है, लेकिन मैं यह करना चाहिए सिर्फ इसलिए कि मैं कर सकता? कोड के पहले ब्लॉक में अधिक टाइपिंग और अधिक कक्षाओं की आवश्यकता होती है, लेकिन यह एक रिश्ते दिखाती है। कोड के दूसरे ब्लॉक के साथ, सबकुछ अधिक "निराकार" है। कौन सा वांछनीय है, और यदि यह मामला-दर-मामला आधार है, तो दिशानिर्देश क्या हैं?

उत्तर

9

सिग्नल को कम करने से कुछ स्विच और कुछ अतिरिक्त फ़ंक्शन कॉल (जो और कैसे जुड़ा हुआ है) के आधार पर, लेकिन ओवरहेड न्यूनतम होना चाहिए।

सिग्नल के प्रदाता का कोई नियंत्रण नहीं है कि उसके ग्राहक कौन हैं और भले ही उन्हें वास्तव में समय के रिमोट द्वारा सिग्नल मिल जाए।

यह बहुत सुविधाजनक है और पूर्ण decoupling की अनुमति देता है, लेकिन निष्पादन मामलों के आदेश या जब आप कुछ वापस करना चाहते हैं तो समस्याएं भी पैदा कर सकते हैं।

कभी भी अस्थायी डेटा पर पॉइंटर्स में पास न करें (जब तक कि आप बिल्कुल नहीं जानते कि आप क्या कर रहे हैं और फिर भी ...)। यदि आपको जरूरी है, तो अपने सदस्य चर के पते को पास करें - क्यूटी ऑब्जेक्ट के विनाश में देरी करने का एक तरीका प्रदान करता है जब तक कि इसके लिए सभी घटनाओं को संसाधित नहीं किया जाता है।

संकेतों को ईवेंट लूप को चलाने की भी आवश्यकता हो सकती है (जब तक कि कनेक्शन सीधे मुझे लगता है)।

कुल मिलाकर वे ईवेंट संचालित अनुप्रयोगों में बहुत अधिक समझ में आते हैं (वास्तव में यह उनके बिना बहुत परेशान हो जाता है)।

यदि आप पहले से ही किसी प्रोजेक्ट में क्यूटी का उपयोग कर रहे हैं, तो निश्चित रूप से उनका उपयोग करें। यदि क्यूटी पर निर्भरता अस्वीकार्य है, तो बूस्ट में एक समान तंत्र है।

3

एक और अंतर है। # 1 आईडीटाब्लॉक इंटरफ़ेस के साथ कठिन है, और अपडेटर क्लास को "कुछब्लॉक" के बारे में जानना आवश्यक है। # 2 को एक कनेक्ट कॉल (या कई डिस्कनेक्ट सहित) के माध्यम से देर से युग्मित किया जा सकता है, जो अधिक गतिशील दृष्टिकोण की ओर जाता है। # 2 एक संदेश की तरह कार्य करता है (लगता है कि स्मॉलटॉक/ओबीजेसी) और कॉल नहीं (सी/सी ++ सोचें)। संदेश एकाधिक प्रेषण के अधीन भी हो सकते हैं, जिसके लिए उस सुविधा को # 1 में लागू करने की आवश्यकता होती है।

मेरी वरीयता उनके लचीलेपन के कारण सिग्नल/स्लॉट का उपयोग करना होगा, जब तक कोड प्रदर्शन या तत्काल वापसी डेटा की आवश्यकता इसके लिए अनुमति न दे (या क्यूटी पर निर्भरता वांछनीय नहीं है)।

2

दो रूप समान दिख सकते हैं। कार्यात्मक रूप से, यह सच है। अभ्यास में, आप एक बड़ी समस्या को हल कर रहे हैं। उन मामलों में, बाहरी परिस्थितियों से इन दो soltuions बराबर नहीं होगा।

एक आम मामला स्रोत और सिंक के बीच संबंध का पता लगा रहा है। क्या वे एक-दूसरे को भी जानते हैं? आपके पहले उदाहरण में, अपडेटडाटा() को सिंक पास होने की आवश्यकता है। लेकिन अगर ट्रिगर एक जीयूआई बटन [अपडेट डेटा] है तो क्या होगा? पुशबूटन सामान्य घटक हैं और आईडीटाब्लॉक के बारे में नहीं जानना चाहिए।

एक समाधान निश्चित रूप से अद्यतनकर्ता को m_someblock सदस्य जोड़ने का है। पुशबटन अब अपडेटर में जो भी सदस्य अपडेट करेगा अपडेट करेगा। लेकिन क्या यह वास्तव में आप क्या चाहते हैं?

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