आइए इन दावों को वास्तविक औसत दर्जे की घटनाओं में तोड़ दें:
- हल्का: क्यूटी कंटेनर एसटीएल कंटेनरों की तुलना में कम मेमोरी का उपयोग करते हैं
- सुरक्षित: क्यूटी कंटेनरों का अनुचित तरीके से उपयोग करने का अवसर कम है
- आसान: क्यूटी कंटेनर एक बौद्धिक बोझ कम प्रस्तुत करते हैं
आसान
इस संदर्भ में किया गया दावा यह है कि जावा शैली की पुनरावृत्ति एसटीएल शैली की तुलना में किसी तरह "आसान" है, और इसलिए क्यूटी को इस अतिरिक्त इंटरफ़ेस के कारण उपयोग करना आसान है।
जावा शैली:
QListIterator<QString> i(list);
while (i.hasNext())
qDebug() << i.next();
एसटीएल शैली:
QList<QString>::iterator i;
for (i = list.begin(); i != list.end(); ++i)
qDebug << *i;
जावा इटैलर स्टाइल में थोड़ा छोटा और क्लीनर होने का लाभ है। समस्या यह है, यह वास्तव में अब एसटीएल शैली नहीं है।
सी ++ 11 एसटीएल स्टाइल
for( auto i = list.begin(); i != list.end(); ++i)
qDebug << *i;
या
C ++ 11 फ़ॉरच स्टाइल
for (QString i : list)
qDebug << i;
जो इतना सरल है कि कभी भी किसी और चीज का उपयोग करने का कोई कारण नहीं है (जब तक कि आप C ++ 11 का समर्थन नहीं करते)।
मेरा पसंदीदा, हालांकि, है:
BOOST_FOREACH(QString i, list)
{
qDebug << i;
}
इसलिए, जैसा कि हम देख सकते हैं, यह इंटरफ़ेस हमें अतिरिक्त इंटरफ़ेस के अलावा कुछ नहीं देता है, पहले से ही चिकना, सुव्यवस्थित और आधुनिक इंटरफ़ेस के शीर्ष पर। पहले से ही स्थिर और प्रयोग करने योग्य इंटरफ़ेस के शीर्ष पर अमूर्तता का अनावश्यक स्तर जोड़ना? "आसान" के मेरे विचार नहीं।
इसके अलावा, क्यूटी फॉरचेक और जावा इंटरफेस ओवरहेड जोड़ते हैं; वे संरचना की नकल करते हैं, और अप्रत्यक्ष स्तर का एक अनावश्यक स्तर प्रदान करते हैं। यह बहुत ज्यादा नहीं लग सकता है, लेकिन एक बहुत अधिक सरल इंटरफ़ेस प्रदान करने के लिए ओवरहेड की एक परत क्यों जोड़ें? जावा में यह इंटरफ़ेस है क्योंकि जावा में ऑपरेटर ओवरलोडिंग नहीं है; सी ++ करता है।
सुरक्षित
Qt जो औचित्य देता है वह निहित बंटवारे की समस्या है, जो न तो निहित है और न ही समस्या है। हालाँकि इसमें साझाकरण शामिल है।
QVector<int> a, b;
a.resize(100000); // make a big vector filled with 0.
QVector<int>::iterator i = a.begin();
// WRONG way of using the iterator i:
b = a;
/*
Now we should be careful with iterator i since it will point to shared data
If we do *i = 4 then we would change the shared instance (both vectors)
The behavior differs from STL containers. Avoid doing such things in Qt.
*/
पहला, यह निहित नहीं है; आप स्पष्ट रूप से एक वेक्टर को दूसरे को सौंप रहे हैं। STL iterator विनिर्देश स्पष्ट रूप से इंगित करता है कि पुनरावृत्त कंटेनर के हैं, इसलिए हमने स्पष्ट रूप से b और a के बीच एक साझा कंटेनर पेश किया है। दूसरा, यह कोई समस्या नहीं है; जब तक पुनरावृत्ति विनिर्देश के सभी नियमों का पालन किया जाता है, तब तक कुछ भी गलत नहीं होगा। केवल समय कुछ गलत हो जाता है:
b.clear(); // Now the iterator i is completely invalid.
Qt इसे निर्दिष्ट करता है जैसे कि इसका मतलब कुछ है, जैसे कि इस परिदृश्य से कोई समस्या उत्पन्न होती है। यह नहीं है पुनरावृत्त को अमान्य कर दिया गया है, और कुछ भी ऐसा है जो कई अलग-अलग क्षेत्रों से पहुँचा जा सकता है, यह सिर्फ यह है कि यह कैसे काम करता है। वास्तव में, यह क्यूटी में जावा शैली के पुनरावृत्तियों के साथ आसानी से घटित होगा, इसके लिए अंतर्निहित साझाकरण पर बहुत अधिक निर्भरता है, जो कि यहां दस्तावेज के रूप में एक एंटीपैटर्न है , और कई अन्य क्षेत्रों में । यह इस "अनुकूलन" के लिए विशेष रूप से अजीब लगता है कि इसे मल्टीथ्रेडिंग की ओर अधिक से अधिक बढ़ने की रूपरेखा में उपयोग में लाया जाना चाहिए, लेकिन यह आपके लिए विपणन है।
लाइटर
यह थोड़ा पेचीदा मामला है। कॉपी-ऑन-राइट और इंप्लिक्ट शेयरिंग और ग्रोथ स्ट्रैटिजिज का उपयोग वास्तव में इस बात की गारंटी देना बहुत मुश्किल हो जाता है कि किसी भी समय आपके कंटेनर में कितनी मेमोरी होगी। यह एसटीएल के विपरीत है, जो आपको मजबूत एल्गोरिथम की गारंटी देता है।
हम जानते हैं कि एक वेक्टर के लिए व्यर्थ की न्यूनतम सीमा वेक्टर की लंबाई का वर्गमूल है , लेकिन Qt में इसे लागू करने का कोई तरीका नहीं है; विभिन्न "अनुकूलन" जो वे समर्थन करते हैं, यह बहुत महत्वपूर्ण स्थान बचत सुविधा को रोक देगा। एसटीएल को इस सुविधा की आवश्यकता नहीं है (और अधिकांश दोहरीकरण वृद्धि का उपयोग करते हैं, जो अधिक बेकार है), लेकिन यह ध्यान रखना महत्वपूर्ण है कि आप कम से कम इस सुविधा को लागू कर सकते हैं, यदि आवश्यक हो।
यह दोहरी रूप से जुड़ी सूचियों के बारे में सच है, जो XOr को जोड़ने के लिए उपयोग किए गए स्थान को काफी कम कर सकता है। फिर, यह क्यूटी के साथ असंभव है, क्योंकि यह विकास और गाय की आवश्यकताओं के कारण है।
गाय वास्तव में कुछ हल्का कर सकते हैं, लेकिन इतना घुसपैठ कंटेनर, जैसे कि बूस्ट द्वारा समर्थित है , और क्यूटी ने इनका उपयोग अक्सर पहले के संस्करणों में किया था, लेकिन इनका उपयोग अब और नहीं किया जाता है क्योंकि वे उपयोग करना मुश्किल है, असुरक्षित हैं, और एक बोझ लगाते हैं प्रोग्रामर पर। गाय एक बहुत कम घुसपैठ समाधान है, लेकिन उपरोक्त कारणों के लिए बदसूरत है।
ऐसा कोई कारण नहीं है कि आप एसटीएल कंटेनरों को उसी मेमोरी लागत या क्यूटी के कंटेनरों से कम का उपयोग नहीं कर सकते हैं, वास्तव में यह जानने के अतिरिक्त लाभ के साथ कि आप किसी भी समय कितना मेमोरी बर्बाद करेंगे। कच्चे स्मृति उपयोग में दोनों की तुलना करना दुर्भाग्य से असंभव है, क्योंकि इस तरह के बेंचमार्क अलग-अलग उपयोग के मामलों में बेतहाशा भिन्न परिणाम दिखाएंगे, जो कि एसटीएल को सही करने के लिए डिज़ाइन की गई समस्या का सटीक प्रकार है।
निष्कर्ष के तौर पर
जब भी संभव हो क्यूटी कंटेनरों के उपयोग से बचें, ताकि एक प्रतिलिपि लागत लगाए बिना, और जब भी संभव हो STL प्रकार का उपयोग करें (शायद एक आवरण या नए सिंटैक्स के माध्यम से)।