कॉपी-ऑन-राइट शब्दार्थ का गुण


10

मैं सोच रहा हूं कि कॉपी-ऑन-राइट में क्या संभावित गुण हैं? स्वाभाविक रूप से, मैं व्यक्तिगत राय की उम्मीद नहीं करता, लेकिन वास्तविक दुनिया के व्यावहारिक परिदृश्य जहां यह तकनीकी और व्यावहारिक रूप से एक लाभप्रद तरीके से फायदेमंद हो सकता है। और मूर्त द्वारा मेरा मतलब है कि आप एक &चरित्र के प्रकार को बचाने से अधिक कुछ कर सकते हैं ।

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

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

एक उदाहरण:

QString s("some text");
QString s1 = s; // now both s and s1 internally use the same resource

qDebug() << s1; // const operation, nothing changes
s1[o] = z; // s1 "detaches" from s, allocates new storage and modifies first character
           // s is still "some text"

इस उदाहरण में गाय का उपयोग करके हम क्या जीतते हैं?

अगर हम सब करना चाहते हैं तो कांस्ट ऑपरेशन का उपयोग करें, s1बेमानी है, साथ ही साथ उपयोग कर सकते हैं s

यदि हम मान को बदलने का इरादा रखते हैं, तो गाय केवल पहले गैर-कॉन्स्टेबल ऑपरेशन तक संसाधन प्रतिलिपि को विलंबित करती है, (यद्यपि न्यूनतम) अंतर्निहित शेयरिंग के लिए रेफरी की गिनती बढ़ाने और साझा भंडारण से अलग करने की लागत। ऐसा लगता है कि गाय में शामिल सभी उपरि व्यर्थ है।

यह पैरामीटर पासिंग के संदर्भ में बहुत अलग नहीं है - यदि आप मान को संशोधित करने का इरादा नहीं रखते हैं, तो कॉन्स्ट संदर्भ के रूप में पास करें, यदि आप संशोधित करना चाहते हैं, तो आप या तो एक अंतर्निहित गहरी प्रतिलिपि बनाते हैं यदि आप संशोधित नहीं करना चाहते हैं यदि आप इसे संशोधित करना चाहते हैं, तो मूल ऑब्जेक्ट, या संदर्भ द्वारा पास करें। फिर से गाय अनावश्यक जरूरत की तरह लगता है कि कुछ भी हासिल नहीं करता है, और केवल एक सीमा जोड़ता है कि आप मूल मूल्य को संशोधित नहीं कर सकते हैं, भले ही आप चाहें, क्योंकि कोई भी बदलाव मूल वस्तु से अलग हो जाएगा।

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

मेरे लिए ऐसा लगता है कि अधिक कुशल और अधिक पठनीय समाधान हैं चाहे आप एक अनावश्यक गहरी प्रतिलिपि से बचना चाहते हैं, या आप एक बनाने का इरादा रखते हैं। तो गाय से व्यावहारिक लाभ कहां है? मुझे लगता है कि इस तरह के एक लोकप्रिय और शक्तिशाली ढांचे में इस्तेमाल होने के बाद से कुछ लाभ होना चाहिए।

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

जवाबों:


15

लिखने पर कॉपी का उपयोग उन स्थितियों में किया जाता है जहां आप अक्सर ऑब्जेक्ट की एक प्रति बनाएंगे और इसे संशोधित नहीं करेंगे। उन स्थितियों में, यह खुद के लिए भुगतान करता है।

जैसा कि आपने उल्लेख किया है, आप एक कास्ट ऑब्जेक्ट पास कर सकते हैं, और कई मामलों में यह पर्याप्त है। हालाँकि, कॉन्स्ट केवल गारंटी देता है कि कॉलर इसे म्यूट नहीं कर सकता (जब तक कि वे const_cast, निश्चित रूप से)। यह मल्टीथ्रेडिंग मामलों को हैंडल नहीं करता है और यह उन मामलों को हैंडल नहीं करता है जहां कॉलबैक होते हैं (जो मूल ऑब्जेक्ट को म्यूट कर सकते हैं)। मान द्वारा एक COW ऑब्जेक्ट को पास करना एपीआई डेवलपर पर इन विवरणों को प्रबंधित करने की चुनौतियों को एपीआई उपयोगकर्ता के बजाय डालता है।

std::stringविशेष रूप से C + 11 निषिद्ध के लिए नए नियम । बैकिंग बफर अलग होने पर एक स्ट्रिंग पर Iterators अमान्य होना चाहिए। यदि पुनरावृत्त को एक char*( string*एक अनुक्रमणिका के विपरीत) के रूप में लागू किया जा रहा था , तो यह पुनरावृत्त अब मान्य नहीं हैं। C ++ समुदाय को यह तय करना था कि पुनरावृत्तियों को कितनी बार अमान्य किया जा सकता है, और निर्णय यह था कि operator[]उन मामलों में से एक नहीं होना चाहिए। operator[]एक std::stringरिटर्न पर char&, जिसे संशोधित किया जा सकता है। इस प्रकार, operator[]स्ट्रिंग को अलग करने की आवश्यकता होगी, पुनरावृत्तियों को अमान्य करना। यह एक खराब व्यापार माना जाता था, और जैसे कार्यों के विपरीत end()और cend(), operator[]स्ट्रिंग को कम करने के लिए कॉस्ट के लघु संस्करण के लिए पूछने का कोई तरीका नहीं है । ( संबंधित )।

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


एक ही स्ट्रिंग को कई थ्रेड में म्यूट करना एक बहुत ही खराब डिज़ाइन की तरह लगता है, भले ही आप पुनरावृत्तियों या []ऑपरेटर का उपयोग करें । इसलिए गाय खराब डिज़ाइन को सक्षम करता है - जो कि एक लाभ की तरह नहीं लगता है :) अंतिम पैराग्राफ में बिंदु मान्य लगता है, लेकिन मैं खुद निहित व्यवहार का बहुत बड़ा प्रशंसक नहीं हूं - लोग इसे लेने के लिए तैयार हैं, और फिर एक कठिन समय यह पता लगाने में क्यों कोड अपेक्षित के रूप में काम नहीं करता है, और जब तक वे अंतर्निहित व्यवहार के पीछे छिपा हुआ है, यह जांचने के लिए सोचता रहता है।
dtech

का उपयोग करने के बिंदु के लिए के रूप में const_castलगता है कि यह टूट सकता है गाय बस के रूप में आसानी से के रूप में यह संदर्भ द्वारा पारित कर सकते हैं। उदाहरण के लिए, QString::constData()रिटर्न const QChar *- a const_castऔर - और कोलैप्स - आप मूल ऑब्जेक्ट के डेटा को म्यूट कर देंगे।
dtech

यदि आप एक गाय से डेटा वापस कर सकते हैं, तो आपको ऐसा करने से पहले या तो अलग करना होगा, या डेटा को एक ऐसे फॉर्म में वापस करना होगा जो अभी भी गाय को पता है ( char*स्पष्ट रूप से पता नहीं है)। निहित व्यवहार के लिए, मुझे लगता है कि आप सही हैं, इसके साथ मुद्दे हैं। एपीआई डिजाइन दो चरम सीमाओं के बीच एक निरंतर संतुलन है। बहुत निहित है, और लोग विशेष व्यवहार पर भरोसा करना शुरू करते हैं जैसे कि यह कल्पना का वास्तविक हिस्सा था। बहुत स्पष्ट है, और एपीआई बहुत अधिक अनपेक्षित हो जाता है क्योंकि आप बहुत सारे अंतर्निहित विवरणों को उजागर करते हैं जो वास्तव में महत्वपूर्ण नहीं थे, और अचानक आपके एपीआई युक्ति में लिखे गए हैं।
Cort Ammon

मेरा मानना ​​है कि stringकक्षाओं को गाय व्यवहार मिला क्योंकि संकलक डिजाइनरों ने देखा कि कोड का एक बड़ा शरीर कॉन्स्टेंस-रेफ़रेंस का उपयोग करने के बजाय स्ट्रिंग्स की नकल कर रहा था। अगर वे गाय को जोड़ते हैं, तो वे इस मामले को अनुकूलित कर सकते हैं और अधिक लोगों को खुश कर सकते हैं (और यह सी +11 तक कानूनी था)। मैं उनकी स्थिति की सराहना करता हूं: जब मैं हमेशा अपने तार को कॉन्स्टेंस संदर्भ से गुजारता हूं, तो मुझे वह सभी वाक्यात्मक कबाड़ दिखाई देता था, जो सिर्फ पठनीयता में बाधक होता है। मुझे const std::shared_ptr<const std::string>&सिर्फ सही शब्दार्थ को पकड़ने के लिए लेखन से नफरत है !
Cort Ammon

5

स्ट्रिंग्स के लिए और ऐसा लगता है कि यह अधिक सामान्य उपयोग के मामलों को कम नहीं करेगा, क्योंकि स्ट्रिंग्स के लिए सामान्य मामला अक्सर छोटे तार होते हैं, और वहां गाय का ओवरहेड छोटी स्ट्रिंग को कॉपी करने की लागत को दूर कर देगा। एक छोटी सी बफ़र ऑप्टिमाइज़ेशन मेरे लिए बहुत अधिक मायने रखती है क्योंकि स्ट्रिंग प्रतियों के बजाय ऐसे मामलों में ढेर आवंटन से बचने के लिए।

यदि आपके पास एक हेफ्टियर ऑब्जेक्ट है, हालांकि, एक एंड्रॉइड की तरह, और आप इसे कॉपी करना चाहते हैं और बस इसकी साइबरनेटिक भुजा को बदलना चाहते हैं, तो गाय एक पारस्परिक रूप से सिंटैक्स रखने के तरीके के रूप में काफी उचित लगता है, जबकि पूरे एंड्रॉइड को केवल गहरी कॉपी करने से बचना चाहिए प्रतिलिपि एक अद्वितीय हाथ दे। उस बिंदु पर एक निरंतर डेटा संरचना के रूप में इसे अपरिवर्तनीय बनाना बेहतर हो सकता है, लेकिन व्यक्तिगत एंड्रॉइड भागों पर लागू "आंशिक गाय" इन मामलों के लिए उचित लगता है।

ऐसे मामले में एंड्रॉइड की दो प्रतियां एक ही धड़, पैर, पैर, सिर, गर्दन, कंधे, श्रोणि, आदि को साझा / उदाहरण देंगी। केवल डेटा जो उनके बीच अलग होगा और साझा नहीं किया जाएगा वह बांह है जो बनाया गया था अपनी बांह पर लिखावट पर दूसरे Android के लिए अद्वितीय है।


यह सब अच्छा है, लेकिन यह गाय की मांग नहीं करता है, और अभी भी बहुत हानिकारक हानिकारकता के अधीन है। इसके अलावा, इसका एक नकारात्मक पहलू है - आप अक्सर ऑब्जेक्ट इंस्टेंसिंग करना चाह सकते हैं, और मेरा मतलब टाइप इंस्टेंसिंग नहीं है, लेकिन किसी ऑब्जेक्ट को उदाहरण के रूप में कॉपी करें, इस प्रकार जब आप सोर्स ऑब्जेक्ट को संशोधित करते हैं, तो कॉपी भी अपडेट हो जाती हैं। गाय बस उस संभावना को बाहर करता है, क्योंकि किसी "साझा" ऑब्जेक्ट में कोई भी परिवर्तन उसे मिटा देता है।
dtech

सुधार आईएमओ को "आसान" नहीं होना चाहिए, न कि निहित व्यवहार के साथ। शुद्धता का एक अच्छा उदाहरण CONST शुद्धता है, क्योंकि यह स्पष्ट है और अस्पष्टता या अदृश्य दुष्प्रभावों के लिए कोई जगह नहीं छोड़ता है। इस तरह से "आसान" और स्वचालित होने से यह कभी नहीं समझ में आता है कि चीजें कैसे काम करती हैं, यह समझने का अतिरिक्त स्तर, जो न केवल समग्र उत्पादकता के लिए महत्वपूर्ण है, बल्कि बहुत हद तक अवांछित व्यवहार की संभावना को समाप्त करता है, जिसके कारण को इंगित करना मुश्किल हो सकता है। । स्पष्ट रूप से अच्छी तरह से प्राप्त करने के लिए गाय के साथ सब कुछ संभव है, और यह अधिक स्पष्ट है।
dtech

मेरा सवाल एक दुविधा से प्रेरित था कि मैं जिस भाषा पर काम कर रहा हूं, उसमें डिफ़ॉल्ट रूप से गाय को प्रदान करना है या नहीं। समर्थक और चोर के वजन के बाद, मैंने इसे डिफ़ॉल्ट रूप से नहीं करने का फैसला किया, लेकिन एक संशोधक के रूप में जिसे नए या पहले से मौजूद दोनों प्रकारों पर लागू किया जा सकता है। दोनों दुनिया के सर्वश्रेष्ठ की तरह लगता है, आप अभी भी गाय का अनुमान लगा सकते हैं, जब आप इसे चाहते हैं।
dtech

@adriver हमारे पास जो कुछ है वह नोडल प्रतिमान के साथ एक प्रोग्रामिंग भाषा के समान है, सरलता के अलावा नोड्स तरह के उपयोग मूल्य शब्दार्थ और बिना संदर्भ-प्रकार के शब्दार्थ (शायद कुछ हद तक std::vector<std::string>हम पहले emplace_backऔर सी +11 में शब्दार्थ को स्थानांतरित करने के लिए) । लेकिन हम मूल रूप से इंस्टेंस का उपयोग भी कर रहे हैं। नोड सिस्टम डेटा को संशोधित कर सकता है या नहीं भी कर सकता है। हमारे पास पास-थ्रू नोड्स जैसी चीजें हैं जो इनपुट के साथ कुछ भी नहीं करते हैं, लेकिन सिर्फ एक प्रति आउटपुट करते हैं (वे अपने कार्यक्रम के उपयोगकर्ता संगठन के लिए वहां हैं)। उन मामलों में, सभी डेटा को जटिल प्रकारों के लिए कॉपी किया जाता है ...

@ddriver हमारी कॉपी-ऑन-राइट प्रभावी रूप से "परिवर्तन पर अद्वितीय रूप से अद्वितीय रूप से स्पष्ट रूप से नकल की प्रक्रिया " है। यह मूल को संशोधित करना असंभव बनाता है। यदि ऑब्जेक्ट Aकी प्रतिलिपि बनाई गई है और ऑब्जेक्ट के लिए कुछ भी नहीं किया गया है B, तो यह जाल जैसे जटिल डेटा प्रकारों के लिए एक सस्ती उथली प्रति है। अब यदि हम संशोधित करते हैं B, तो हम जिस डेटा को संशोधित करते हैं , वह Bगाय के माध्यम से अद्वितीय हो जाता है, लेकिन Aअछूता रहता है (कुछ परमाणु संदर्भ गणना को छोड़कर)।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.