[C++] लाइब्रेरी के सार्वजनिक इंटरफ़ेस में बढ़ावा :: साझा_पीटीआर का उपयोग करना


Answers

एक संभव समाधान अपने प्रोजेक्ट के साथ बढ़ावा :: साझा किया गया है। चूंकि यह सभी शीर्ष लेखकों के होते हैं, यह आपके ग्राहकों को मैन्युअल रूप से बढ़ावा देने वाले पुस्तकालयों को स्थापित करने से मुक्त करेगा। आप बीसीपी का उपयोग सभी पुस्तकालयों द्वारा आवश्यक सभी फ़ाइलों को हासिल करने के लिए कर सकते हैं, जिसमें पुस्तकालयों को शामिल किया गया है मैंने ऐसा किया जब मैंने एक कंपनी के लिए वापस काम किया और boost::shared_ptr आवश्यकता boost::shared_ptr और यह वास्तव में बहुत काम किया

Question

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

संपादित करें: मैंने मूल रूप से स्वामित्व का हस्तांतरण कहा था, लेकिन मुझे यह निर्दिष्ट करना चाहिए था कि एपीआई सीमा के दोनों किनारों पर कोड को ऑब्जेक्ट पर एक पॉइंटर रखना होगा।




auto_ptr उपयोग करें या सी इंटरफ़ेस पर auto_ptr । आपके इंटरफ़ेस में सी ++ लिब्स को मजबूर करना हमेशा कुरूप होता है, क्रॉस प्लेटफॉर्म होने की कोई भी मौत को मारता है, और विभिन्न "डाउनस्ट्रीम" कॉन्फ़िगरेशन वाले ग्राहकों के लिए रखरखाव दुःस्वप्न का कारण बनता है

जैसे ही सी ++ 0x आपके क्लाइंट के लिए मुख्य धारा है, std::shared_ptr स्विच करें।







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

यदि आप कच्चे पॉइंटर्स का उपयोग करते हैं, तो आप सभी प्रकार की संभावनाओं को अनुमति देते हैं। उपयोगकर्ता कोड एक कच्चे पॉइंटर का उपयोग कर सकता है, इसे std :: auto_ptr, shared_ptr (चाहे बढ़ावा या TR1), या स्मार्ट पॉइंटर के उनके घर के संस्करण में संग्रहीत कर सकता है। लेकिन यह उपयोगकर्ता को परेशानी में भी प्राप्त कर सकता है अगर वे स्मृति को छोड़ना भूल जाते हैं, और उनके पक्ष में कुछ और कोड की आवश्यकता होती है, यदि वे एक विधि कॉल के लिए अस्थायी रूप से तैयार करना चाहते हैं (यदि आप कच्चे पॉइंटर्स प्रदान करते हैं, तो उन्हें स्टोर करना होगा पॉन्टर गैर-अस्थायी [संभवतः स्मार्ट] पॉइंटर चर में)।

अब, यदि आप एक स्मार्ट पॉइंटर का उपयोग करते हैं तो आप उपयोगकर्ता में अपने समाधान को मजबूर कर रहे हैं। यदि वे स्मार्ट पॉइंटर के अपने संस्करण का उपयोग करने की योजना बनाते हैं (कहते हैं कि आप boost :: shared_ptr का उपयोग करते हैं और वे std :: tr1 :: shared_ptr चाहते हैं) वे इसे अपने इंटरफ़ेस के साथ काम करते हैं, तो इसका उपयोग करने की अनुमति नहीं दी जाती है जो भी स्मार्ट पॉइंटर आप पर फैसला करते हैं (std :: auto_ptr के अलावा विशेष है) आप केवल एक समाधान को मजबूर नहीं कर रहे हैं, बल्कि यह भी समस्याएं हैं।

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

एक तरफ नोट के रूप में, बढ़ावा: :: shared_ptr (1.33+ को बढ़ावा) अधिकांश स्थितियों में सुरक्षित है, और यह कई प्लेटफार्मों में लॉक-फ्री कार्यान्वयन का उपयोग करता है। वैसे भी यह आपको उन चीजों का विचार देना चाहिए जिन पर आपको विचार करना चाहिए।

अंत में, आपको यह विचार करना चाहिए कि आप उपयोगकर्ता को केवल अपने प्रकार के स्मार्ट पॉइंटर का उपयोग करने में बाध्यकारी नहीं हैं, बल्कि इसका एक ही संस्करण भी है। यदि आप को बढ़ावा देने के एक विशेष संस्करण के खिलाफ अपनी लिब संकलन उपयोगकर्ता उस विशेष कार्यान्वयन ओ के लिए बाध्य है




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

मैं व्यक्तिगत तौर पर सोचता हूं कि आपको अपनी लाइब्रेरी के सार्वजनिक इंटरफ़ेस में बहुत सी दिखने वाली सी ++ से बचना चाहिए क्योंकि इससे क्लाइंट पर कई समस्याएं हो सकती हैं।

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

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

विभिन्न सी ++ कंपाइलर्स और वातावरण की वर्तमान दुनिया में मुझे लगता है कि दुखद सत्य यह है कि आपको अपने इंटरफ़ेस में कुछ भी नहीं बल्कि सी होने से बचना चाहिए और सुनिश्चित करें कि आप अपने पुस्तकालय को गतिशील रूप से लिंक करते हैं (अपने ग्राहकों को लिंक करते समय संघर्ष से बचने के लिए आपकी लाइब्रेरी, विंडो रनटाइम लाइब्रेरी एक असली दर्द हो सकता है यहाँ)। आप अभी भी अपनी लाइब्रेरी के अंदर बूस्ट और बहुत फैंसी सी ++ का उपयोग कर सकते हैं क्योंकि आप चाहते हैं कि आपके सभी प्रतीकों को डीएलएल में अपने ग्राहकों के वातावरण से अलग किया जाएगा।

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

एक और अच्छी विशेषता यह है कि सी ++ फ़ंक्शन से सी फ़ंक्शन को अजीब नाम मैंगलिंग के साथ कॉल करना आसान होता है यदि आप सी / सी ++ की तुलना में अपनी लाइब्रेरी को अन्य भाषाओं में प्रदर्शित करना चाहते हैं।

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