2009-05-11 7 views
15

एसटीएल और बूस्ट के साथ मिश्रित क्यूटी बनाने के लिए कोई पुल हैं जहां तक ​​संभव और सहज हो सके?एसटीएल और बूस्ट के साथ मिक्सिंग क्यूटी - क्या इसे आसान बनाने के लिए कोई पुल हैं?

यह Mixing Qt and Boost पर एक फॉलोअप है, जहां इसे पूरा करने के लिए कोई विशिष्ट उत्तर नहीं दिया गया था।

+0

वास्तव में आप क्या कर रहे हैं: एक सामान्य सूचक (shared_ptr की तरह) के रूप में QPointer संभाल करने के लिए बाध्य के बारे में चिंतित? सिद्धांत रूप में, ऐसे कई क्षेत्र नहीं होने चाहिए जहां दोनों बूस्ट और क्यूटी को सहवास करने की आवश्यकता होगी। – Kena

+0

मुझे अभी तक कोई समस्या नहीं है क्योंकि मुझे क्यूटी पता चल रहा है लेकिन क्यूटी, एसटीएल और बूस्ट के बीच यह बहुत अधिक ओवरलैप है। मुझे यकीन है कि वहां कई जगहें हैं जहां कुछ प्रकार की मार्शलिंग की आवश्यकता है। यह .NET और C++ के समान है; यही वजह है कि एम $ मार्शलिंग लाइब्रेरी के साथ आया था। मैं उन चीज़ों के लिए तैयार होने की कोशिश कर रहा हूं जिनसे मैं बच नहीं सकता। –

+14

सबसे पहले, कंपनी को माइक्रोसॉफ्ट, संक्षेप में एमएस कहा जाता है। केवल 13 वर्षीय स्क्रिप्ट किड्स उन्हें एम $ कहते हैं। दूसरा, .NET/C++ इंटरऑप एक पूरी तरह से अलग जानवर है, क्योंकि आप पूरी तरह से अलग प्लेटफ़ॉर्म, प्रबंधित और अप्रबंधित कोड के बीच संचार कर रहे हैं। क्यूटी और बूस्ट सी ++ पुस्तकालय दोनों हैं, एक ही प्रक्रिया में चलते हैं, एक ही रनटाइम और सबकुछ का उपयोग करते हैं। वहाँ कोई marshalling की जरूरत है। – jalf

उत्तर

37

आपको किन पुलों की आवश्यकता है?

आप सभी क्यूटी कंटेनर कक्षाओं का उपयोग std एल्गोरिदम के साथ कर सकते हैं। अधिकांश समय मैं क्यूटी कंटेनर कक्षाओं को पसंद करता हूं क्योंकि मुझे यकीन है कि वे कॉपी-ऑन-राइट मुहावरे (निरंतर समय ऑपरेशन) का उपयोग करते हैं। क्यूटी का foreach फ़ंक्शन कंटेनर की एक प्रति बनाता है, इसलिए यह अच्छा है कि आप निश्चित रूप से जानते हैं कि यह एक स्थिर समय ऑपरेशन है।

क्यूटी संकेत स्लॉट तंत्र धीमा करने के लिए आप को बढ़ावा देने विकल्प को बदल सकते हैं। क्यूटी सिग्नल/स्लॉट के बारे में बड़ी बात दो धागे के बीच सिग्नल/स्लॉट कनेक्शन है।

QtConcurrent BOOST.Lambda


साथ अच्छा काम करता है "साझा" बच्चों के माता पिता के संबंध में मैं इस सहायक समारोह का उपयोग करें।

template <class Object> 
static boost::shared_ptr<Object> makeSharedObject() 
{ 
    using namespace boost; 
    using namespace boost::lambda; 
    return boost::shared_ptr<Object>( 
     new Object(), 
     bind(&Object::deleteLater, _1)); 
} 

क्यूटी कंटेनरों Boost.serialize द्वारा समर्थित नहीं हैं, तो आप serialize कार्यों अपने आप को लिखने के लिए होगा। मुझे क्यूटी स्ट्रीमिंग कक्षाओं और Boost.archive के बीच एक पुल पसंद आएगा।

यहाँ मेरी QList क्रमबद्धता टेम्पलेट आप बाकी को यह पता लगाने कर सकते हैं ...

///\file document is based on "boost/serialization/list.hpp" 

namespace boost { 
    namespace serialization { 

     //--------------------------------------------------------------------------- 
     /// Saves a QList object to a collection 
     template<class Archive, class U > 
     inline void save(Archive &ar, const QList<U> &t, const uint /* file_version */) 
     { 
      boost::serialization::stl::save_collection< Archive, QList<U> >(ar, t); 
     } 

     //--------------------------------------------------------------------------- 
     /// Loads a QList object from a collection 
     template<class Archive, class U> 
     inline void load(Archive &ar, QList<U > &t, const uint /* file_version */) 
     { 
       boost::serialization::stl::load_collection< 
        Archive, 
        QList<U>, 
        boost::serialization::stl::archive_input_seq<Archive, QList<U> >, 
        boost::serialization::stl::no_reserve_imp< QList<U> > >(ar, t); 
     } 

     //--------------------------------------------------------------------------- 
     /// split non-intrusive serialization function member into separate 
     /// non intrusive save/load member functions 
     template<class Archive, class U > 
     inline void serialize(Archive &ar, QList<U> &t, const uint file_version) 
     { 
      boost::serialization::split_free(ar, t, file_version); 
     } 

    } // namespace serialization 
} // namespace boost 

BOOST_SERIALIZATION_COLLECTION_TRAITS(QList) 

आप को बढ़ावा चाहते हैं है।

namespace boost { 

    template<typename T> T * get_pointer(QPointer<T> const& qPointer) 
    { 
     return qPointer; 
    } 
} 

QIODevice का उपयोग करना है, जहां एक std::stream की जरूरत है

namespace boost { 
    namespace iostreams { 

     class IoDeviceSource 
     { 
     public: 
      typedef char char_type; 
      typedef source_tag category; 

      explicit IoDeviceSource(QIODevice& source) 
       : m_source(source) 
      { 
      } 

      std::streamsize read(char* buffer, std::streamsize n) 
      { 
       return return m_source.read(buffer, n); 
      } 
     private: 
      QIODevice& m_source; 
     }; 

     class IoDeviceSink { 

     public: 
      typedef char char_type; 
      typedef sink_tag category; 

      explicit IoDeviceSink(QIODevice& sink) 
       : m_sink(sink) 
      { 
      } 

      std::streamsize write(const char_type* buffer, std::streamsize n) 
      { 
       return m_sink.write(buffer, n); 
      } 

     private: 
      QIODevice &m_sink; 
     }; 

     class IoDeviceDevice { 

     public: 
      typedef char char_type; 
      typedef seekable_device_tag category; 

      explicit IoDeviceDevice(QIODevice& device) 
       :m_device(device) { 
      } 

      std::streamsize write(const char_type *buffer, std::streamsize n) 
      { 
       return m_device.write(buffer, n); 
      } 

      std::streamsize read(char* buffer, std::streamsize n) 
      { 
       return m_device.read(buffer, n); 
      } 

      stream_offset seek(stream_offset off, std::ios_base::seekdir way) 
      { 
       using namespace std; 
       stream_offset next(0); 

       if(way==ios_base::beg) 
       { 
        next = m_device.pos(); 
       } 
       else if(way==ios_base::cur) 
       { 
        next = m_device.pos() + offset; 
       } 
       else if(way==ios_base::end) 
       { 
        next = m_device.size() -1 + offset; 
       } 
       else 
       { 
        throw ios_base::failure("bad seek direction"); 
       } 

       if(!m_device.seek(next)) 
       { 
        throw ios_base::failure("bad seek offset"); 
       } 
       return m_device.pos(); 
      } 

     private:  
      QIODevice &m_device; 
     }; 
    } 
} 

उदाहरण

#include <iostream> 
#include <QFile> 
#include <boost/iostreams/stream.hpp> 
#include "iodevicestream.h" 

int main(int argc, char *argv[]) 
{ 
    namespace io = boost::iostreams; 

    QVector<int> data; 

    QFile fl("temp.bin"); 
    fl.open(QIODevice::ReadWrite); 
    io::stream<io::IoDeviceDevice> inoutput(fl); 

    std::copy(data.begin(), data.end(), std::ostream_iterator<int>(inoutput, "\n")); 
    inoutput.flush(); 
    inoutput.seekg(0, std::ios_base::beg); 
    std::cout << inoutput; 
    return 0; 
} 
+3

@TimW यह अब तक का सबसे अच्छा जवाब है ... असली दुनिया कोड के लिए धन्यवाद। मुझे पता है कि बूस्ट कितना लोकप्रिय है मुझे आशा है कि क्यूटी टीम इस प्रकार के पुलों को ढांचे के हिस्से को बनाने के लिए लोगों को बचाने के लिए ढांचे का हिस्सा बनाती है। मुझे लगता है कि बूस्ट के साथ काम कर रहे डेवलपर्स के बीच क्यूटी के तेजी से गोद लेने में भी मदद मिलेगी। इसे कुछ सी ++ सर्कल में क्यूटी की लोकप्रियता का एक बहुत ही महत्वपूर्ण कारक माना जा सकता है। –

+0

'रास्ता == ios_base :: beg के साथ मामला नहीं होना चाहिए 'तलाश' में 'अगले' को 'ऑफसेट' के बजाय सेट करें 'M_device.pos()'? –

3

समस्या क्या है?
यदि आप चाहते हैं और एसटीएल समकक्षों का उपयोग करते हैं तो आप सभी क्यूटी संग्रह कक्षाओं को अनदेखा कर सकते हैं।
इसी प्रकार आप बूस्ट की क्रॉस प्लेटफ़ॉर्म फ़ाइल/नेटवर्क libs का उपयोग कर सकते हैं।

मुख्य कारण क्यूटी के स्वयं के उपयोग करने के लिए शायद उस बढ़ावा जरूरी नहीं है कि व्यापक रूप से उपलब्ध विशेष रूप से मोबाइल उपकरणों पर। बूस्ट के कुछ काम सरल कार्यों के लिए क्यूटी लोगों की तुलना में थोड़ा अधिक जटिल हैं।

+0

@mgb यह कोई सवाल नहीं है कि किसके बारे में चुनें और क्यों करें लेकिन एक ही समय में दोनों का उपयोग करते समय क्या करना है। टिमडब्ल्यू का जवाब देखें जो मोटे तौर पर मैं उम्मीद कर रहा था। –

+0

ठीक है, मैं देखता हूं, आप इसे फिर से लिखने के लिए प्रश्न संपादित करना चाहेंगे। –

+0

@ एमजीबी उदाहरण: मेरे पास एक सार तत्व आधार वर्ग है जिसे लोड (QIODevice *) फ़ंक्शन लागू करना होगा। एक ImageEXR सबक्लास, जो EXR छवियों को लोड करने के लिए openEXR lib का उपयोग करता है। लेकिन ओपनएक्सआर लोड इनपुट के रूप में एक आईट्रीम का उपयोग करता है और क्यूटी के बारे में नहीं जानता है। – galinette

2

सामान्यतः आप क्यूटी का उपयोग करते समय बेहतर किराया देने जा रहे हैं यदि आप हमारे बजाय एसटीएल के बजाय क्यूटी संग्रह कक्षाओं में रहते हैं। क्यूटी, एसटीएल या बूस्ट में प्रति सीई नहीं है जो एक दूसरे के भीतर उपयोग करने से रोक देगा।

स्मार्ट पॉइंटर्स का उपयोग करते समय आपको सावधान रहना होगा क्यूटी के माता-पिता/बच्चे के रिश्ते हैं जो ऑब्जेक्ट्स के विनाश का ख्याल रख सकते हैं, क्यूटी के नियंत्रण में ऑब्जेक्ट्स को डिलीकेट करने से आपको दुर्घटना हो जाएगी।

+0

यह एक क्यूटी वस्तु को हटाने के लिए पूरी तरह से सुरक्षित है। QObject के विनाशक में यह अपने माता-पिता की बाल सूची से खुद को अनधिकृत कर देगा। बिल्कुल कोई दुर्घटना नहीं –

+1

@Evan, कुछ नुकसान हैं ... http://doc.qtsoftware.com/4.5/objecttrees.html नीचे। –

+0

मुझे अतीत में इसकी समस्याएं थीं। यह उपरोक्त दस्तावेज़ में उल्लिखित आदेश की समस्या के कारण हो सकता है। –

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