C ++ में प्रतिबिंब क्यों नहीं है?


337

यह कुछ हद तक विचित्र सवाल है। मेरा उद्देश्य भाषा डिजाइन निर्णय को समझना और C ++ में प्रतिबिंब की संभावनाओं की पहचान करना है।

  1. C ++ भाषा समिति भाषा में प्रतिबिंब लागू करने की ओर क्यों नहीं गई? क्या वर्चुअल मशीन (जैसे जावा) पर नहीं चलने वाली भाषा में प्रतिबिंब बहुत मुश्किल है?

  2. यदि कोई C ++ के लिए प्रतिबिंब लागू करने के लिए था, तो चुनौतियां क्या होंगी?

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

जवाबों:


631

C ++ में प्रतिबिंब के साथ कई समस्याएं हैं।

  • यह जोड़ने के लिए बहुत काम है, और C ++ समिति काफी रूढ़िवादी है, और कट्टरपंथी नई सुविधाओं पर समय खर्च नहीं करते हैं जब तक कि वे सुनिश्चित न हों कि यह भुगतान करेगा। (.NET असेंबली के समान एक मॉड्यूल सिस्टम जोड़ने का सुझाव दिया गया है, और जब तक मुझे लगता है कि आम सहमति है कि यह अच्छा होगा, फिलहाल यह उनकी सर्वोच्च प्राथमिकता नहीं है, और बाद में अच्छी तरह से पीछे धकेल दिया गया है सी ++ 0x। इस सुविधा के लिए प्रेरणा #includeप्रणाली से छुटकारा पाने के लिए है, लेकिन यह कम से कम कुछ मेटाडेटा को भी सक्षम करेगा)।

  • आप जो उपयोग नहीं करते हैं उसके लिए आप भुगतान नहीं करते हैं। यह C ++ में अंतर्निहित मूल डिज़ाइन दर्शन में से एक है। अगर मुझे कभी इसकी आवश्यकता नहीं हो, तो मेरा कोड मेटाडेटा के आसपास क्यों ले जाना चाहिए? इसके अलावा, मेटाडेटा का जोड़ संकलक को अनुकूलन से रोक सकता है। मुझे अपने कोड में उस लागत का भुगतान क्यों करना चाहिए अगर मुझे उस मेटाडेटा की कभी आवश्यकता नहीं हो सकती है?

  • जो हमें एक और बड़े बिंदु की ओर ले जाता है: C ++ संकलित कोड के बारे में बहुत कम गारंटी देता है। कंपाइलर को बहुत अधिक कुछ भी पसंद करने की अनुमति है, जब तक कि परिणामी कार्यक्षमता वह है जो अपेक्षित है। उदाहरण के लिए, अपनी कक्षाओं वास्तव में करने के लिए आवश्यक नहीं कर रहे हैं वहाँ हो । कंपाइलर उन्हें दूर अनुकूलित कर सकता है, वे जो कुछ भी करते हैं उसे इनलाइन कर सकते हैं, और यह अक्सर ऐसा ही करता है, क्योंकि यहां तक ​​कि सरल टेम्पलेट कोड भी काफी कुछ टेम्पलेट तात्कालिकता पैदा करता है। C ++ मानक पुस्तकालय इस आक्रामक अनुकूलन पर निर्भर करता है । फ़ॉन्टर केवल प्रदर्शन करने वाले होते हैं यदि ऑब्जेक्ट को तत्काल और नष्ट करने के ओवरहेड को दूर अनुकूलित किया जा सकता है। operator[]एक वेक्टर पर केवल प्रदर्शन में कच्चे सरणी अनुक्रमण के लिए तुलनीय है क्योंकि पूरे ऑपरेटर को इनलाइन किया जा सकता है और इस प्रकार पूरी तरह से संकलित कोड से हटा दिया जाता है। C # और Java कंपाइलर के आउटपुट के बारे में बहुत सारी गारंटी देते हैं। यदि मैं C # में एक वर्ग को परिभाषित करता हूं, तो परिणामी विधानसभा में वह वर्ग मौजूद होगा । भले ही मैं इसका इस्तेमाल कभी न करूं। भले ही इसके सदस्य कार्यों के लिए सभी कॉल इनबिल्ट हों। कक्षा वहाँ होनी चाहिए, ताकि प्रतिबिंब उसे खोज सके। इसका एक भाग सी # बायटेकोड के संकलन द्वारा समाप्त किया जाता है, जिसका अर्थ है कि जेआईटी संकलक कर सकता हैवर्ग परिभाषाएँ और इनलाइन फ़ंक्शंस निकालें यदि यह पसंद है, भले ही प्रारंभिक C # संकलक नहीं कर सकता। C ++ में, आपके पास केवल एक कंपाइलर है, और इसे कुशल कोड आउटपुट करना है। यदि आपको C ++ निष्पादन योग्य के मेटाडेटा का निरीक्षण करने की अनुमति दी गई थी, तो आप इसे परिभाषित हर वर्ग को देखने की उम्मीद करेंगे, जिसका अर्थ है कि संकलक को सभी परिभाषित वर्गों को संरक्षित करना होगा, भले ही वे आवश्यक न हों।

  • और फिर टेम्पलेट हैं। C ++ में टेम्प्लेट अन्य भाषाओं में जेनरिक की तरह कुछ भी नहीं हैं। हर टेम्पलेट तात्कालिकता एक नया प्रकार बनाता है । std::vector<int>से एक पूरी तरह से अलग वर्ग है std::vector<float>। यह एक पूरे कार्यक्रम में विभिन्न प्रकार के बहुत से जोड़ता है। हमारा प्रतिबिंब क्या देखना चाहिए? टेम्पलेट std::vector ? लेकिन यह कैसे हो सकता है, क्योंकि यह एक स्रोत-कोड निर्माण है, जिसका रनटाइम पर कोई मतलब नहीं है? यह अलग वर्ग को देखने के लिए होगा std::vector<int>और std::vector<float>। और std::vector<int>::iteratorऔर std::vector<float>::iterator, उसी के लिएconst_iteratorऔर इसी तरह। और एक बार जब आप टेम्पलेट मेटाप्रोग्रामिंग में कदम रखते हैं, तो आप सैकड़ों टेम्पलेट्स को तुरंत समाप्त कर देते हैं, जो सभी संकलित हो जाते हैं और संकलक द्वारा फिर से हटा दिए जाते हैं। उनका कोई अर्थ नहीं है, सिवाय संकलन के समय के मेटाफ्राम के हिस्से के रूप में। क्या इन सभी सैकड़ों वर्गों को परावर्तन के लिए दृश्यमान होना चाहिए? उन्हें करना होगा, क्योंकि अन्यथा हमारा प्रतिबिंब बेकार हो जाएगा, अगर यह भी गारंटी नहीं देता कि जिन वर्गों को मैंने परिभाषित किया है वे वास्तव में वहां होंगे । और एक साइड की समस्या यह है कि टेम्पलेट क्लास तब तक मौजूद नहीं है, जब तक कि इसे तत्काल नहीं किया जाता है। एक कार्यक्रम की कल्पना करें जो उपयोग करता है std::vector<int>। क्या हमारी प्रतिबिंब प्रणाली को देखने में सक्षम होना चाहिए std::vector<int>::iterator? एक तरफ, आप निश्चित रूप से उम्मीद करेंगे। यह एक महत्वपूर्ण वर्ग है, और इसके संदर्भ में परिभाषित किया गया है std::vector<int>, जो करता हैमेटाडेटा में मौजूद है। दूसरी ओर, यदि प्रोग्राम वास्तव में कभी भी इस इटैलर क्लास टेम्पलेट का उपयोग नहीं करता है , तो इसका प्रकार कभी भी त्वरित नहीं होगा, और इसलिए कंपाइलर ने पहली जगह में कक्षा उत्पन्न नहीं की होगी। और इसे रनटाइम पर बनाने के लिए बहुत देर हो चुकी है, क्योंकि इसे स्रोत कोड तक पहुंच की आवश्यकता होती है।

  • और अंत में, C ++ में प्रतिबिंब बहुत महत्वपूर्ण नहीं है क्योंकि यह C # में है। कारण फिर से है, टेम्पलेट मेटाप्रोग्रामिंग। यह सब कुछ हल नहीं कर सकता है, लेकिन कई मामलों के लिए जहां आप अन्यथा प्रतिबिंब का सहारा लेंगे, एक मेटाप्रोग्राम लिखना संभव है जो संकलन-समय पर एक ही काम करता है। boost::type_traitsएक सरल उदाहरण है। आप प्रकार के बारे में जानना चाहते हैं T? इसकी जाँच करें type_traits। C # में, आपको अपने प्रकार के प्रतिबिंब का उपयोग करने के बाद चारों ओर मछली पकड़नी होगी। प्रतिबिंब अभी भी कुछ चीजों के लिए उपयोगी होगा (मुख्य उपयोग जो मैं देख सकता हूं, जो मेटाप्रोग्रामिंग आसानी से प्रतिस्थापित नहीं कर सकता है, ऑटोजेनरेटेड क्रमांकन कोड के लिए है), लेकिन यह सी ++ के लिए कुछ महत्वपूर्ण लागतों को ले जाएगा, और यह बस के रूप में अक्सर आवश्यक नहीं है अन्य भाषाओं में है।

संपादित करें: टिप्पणियों के जवाब में:

cdleary: हाँ, डिबग प्रतीक कुछ ऐसा ही करते हैं, जिसमें वे निष्पादन में उपयोग किए जाने वाले प्रकारों के बारे में मेटाडेटा संग्रहीत करते हैं। लेकिन वे मेरे द्वारा बताई गई समस्याओं से भी पीड़ित हैं। यदि आपने कभी रिलीज़ बिल्ड डीबग करने का प्रयास किया है, तो आपको पता होगा कि मेरा क्या मतलब है। बड़े तार्किक अंतराल हैं जहां आपने स्रोत कोड में एक वर्ग बनाया है, जो अंतिम कोड में दूर हो गया है। यदि आप किसी भी उपयोगी चीज़ के लिए प्रतिबिंब का उपयोग करते हैं, तो आपको अधिक विश्वसनीय और सुसंगत होने की आवश्यकता होगी। जैसा कि यह है, प्रकार आपके द्वारा संकलित किए जाने के लगभग हर बार गायब हो जाते हैं और गायब हो जाते हैं। आप एक छोटे से विस्तार को बदलते हैं, और संकलक को बदलने का फैसला करता है कि किस प्रकार के इनलेट मिलते हैं और जो प्रतिक्रिया के रूप में नहीं होते हैं। जब आप कोई उपयोगी चीज निकालते हैं, तो आप ' यह भी गारंटी नहीं है कि आपके मेटाडेटा में सबसे अधिक प्रासंगिक प्रकार का प्रतिनिधित्व किया जाएगा? आप जिस प्रकार की तलाश कर रहे थे वह अंतिम बिल्ड में हो सकता है, लेकिन अब वह चला गया है। और कल, कोई व्यक्ति एक छोटे से निर्दोष समारोह में एक छोटे से निर्दोष परिवर्तन की जांच करेगा, जो कि प्रकार को केवल इतना बड़ा बनाता है कि यह पूरी तरह से इनलेट नहीं होगा, इसलिए यह फिर से वापस आ जाएगा। यह अभी भी डिबग प्रतीकों के लिए उपयोगी है, लेकिन इससे अधिक नहीं। मैं उन शर्तों के तहत एक वर्ग के लिए क्रमांकन कोड तैयार करने से नफरत करना चाहूंगा। लेकिन उससे ज्यादा नहीं। मैं उन शर्तों के तहत एक वर्ग के लिए क्रमांकन कोड तैयार करने से नफरत करना चाहूंगा। लेकिन उससे ज्यादा नहीं। मैं उन शर्तों के तहत एक वर्ग के लिए क्रमांकन कोड तैयार करने से नफरत करना चाहूंगा।

इवान टेरान: बेशक इन मुद्दों को हल किया जा सकता है। लेकिन यह मेरी बात # 1 पर वापस आती है। यह बहुत काम लेगा, और सी ++ समिति के पास बहुत सारी चीजें हैं जो उन्हें लगता है कि अधिक महत्वपूर्ण हैं। क्या सी ++ में कुछ सीमित प्रतिबिंब (और यह सीमित होगा) का लाभ वास्तव में इतना बड़ा है कि अन्य सुविधाओं की कीमत पर ध्यान केंद्रित करना उचित है? क्या मूल भाषा को जोड़ने में वास्तव में बहुत बड़ा लाभ है जो पहले से ही (ज्यादातर) क्यूटीज़ जैसे पुस्तकालयों और पूर्वप्रक्रमकों के माध्यम से किया जा सकता है? शायद, लेकिन जरूरत बहुत कम जरूरी है अगर ऐसी लाइब्रेरी मौजूद नहीं थी। हालांकि आपके विशिष्ट सुझावों के लिए, मेरा मानना ​​है कि इसे टेम्प्लेट पर रोकना पूरी तरह से बेकार कर देगा। आप मानक पुस्तकालय पर प्रतिबिंब का उपयोग करने में असमर्थ होंगे, उदाहरण के लिए। किस तरह का प्रतिबिंब होगा 'std::vector? टेम्प्लेट C ++ का एक बड़ा हिस्सा हैं। टेम्प्लेट पर काम नहीं करने वाली एक सुविधा मूल रूप से बेकार है।

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

लेकिन जैसा कि मैंने कहा, संकलन मॉडल में बदलाव के लिए एक प्रस्ताव है, स्व-निहित मॉड्यूल को जोड़ना, चुनिंदा प्रकारों के लिए मेटाडेटा संग्रहीत करना, अन्य मॉड्यूल को #includeएस के साथ गड़बड़ किए बिना उन्हें संदर्भित करने की अनुमति देता है । यह एक अच्छी शुरुआत है, और ईमानदार होने के लिए, मुझे आश्चर्य है कि मानक समिति ने प्रस्ताव को बहुत बड़ा बदलाव के लिए नहीं फेंक दिया। तो शायद 5-10 सालों में? :)


2
इन मुद्दों में से अधिकांश को पहले से ही डिबग प्रतीकों द्वारा हल नहीं करना है? ऐसा नहीं है कि यह प्रदर्शन योग्य होगा (क्योंकि आपके द्वारा उल्लिखित इनलाइनिंग और अनुकूलन के कारण), लेकिन आप जो भी डिबग प्रतीक करते हैं, वे प्रतिबिंब की संभावना के लिए अनुमति दे सकते हैं।
cdleary

2
आपके पहले बिंदु के बारे में एक और बात: जहाँ तक मुझे पता है कि किसी ने C ++ कार्यान्वयन में प्रतिबिंब को जोड़ने की कोशिश नहीं की है। इसके साथ कोई अच्छा अनुभव नहीं है। कमेटी शायद लीड लेने के लिए अनिच्छुक है, खासकर exportऔर बाद में vector<bool>
डेविड थॉर्नले

18
मैं इस बात से सहमत हूं कि C ++ में टाइम रिफ्लेक्शन नहीं होना चाहिए। लेकिन संकलन समय प्रतिबिंब में उपरोक्त कुछ समस्याएं हैं, और किसी के लिए विशेष समय पर रन टाइम प्रतिबिंब बनाने के लिए इस्तेमाल किया जा सकता है यदि वे चुनते हैं। टेम्पलेट के माध्यम से वर्ग के nth विधि और nth माता-पिता के प्रकार और नाम और सुविधाओं तक पहुँचने में सक्षम होने के नाते? और संकलन समय पर ऐसी संख्या प्राप्त करें? CRTP को स्वचालित परावर्तन योग्य बनाने योग्य बना देगा, जबकि कोई भी उनके उपयोग के लिए भुगतान नहीं कर रहा है।
यक - एडम नेवरामॉन्ट

15
आपका तीसरा बिंदु कई मामलों में सबसे महत्वपूर्ण है: C ++ का उद्देश्य उन प्लेटफार्मों पर स्टैंडअलोन कोड लिखने के लिए उपयुक्त है जहां मेमोरी में पैसे लगते हैं; अगर कुछ अप्रयुक्त कोड को समाप्त करने से एक कार्यक्रम माइक्रोकंट्रोलर में फिट होने की अनुमति देगा, जिसकी लागत $ 2, बल्कि $ 2.50 है, और यदि कोड 1,000,000 इकाइयों में जा रहा है, तो उस कोड को समाप्त करने से $ 500,000 बच सकते हैं। प्रतिबिंब के बिना, स्थैतिक विश्लेषण अक्सर अगम्य कोड के 90% + की पहचान कर सकता है; यदि परावर्तन की अनुमति है, तो कुछ भी जो प्रतिक्षेपण के माध्यम से पहुँचा जा सकता है, उसे पुन: प्राप्य माना जाना चाहिए, भले ही वह 90% न हो।
सुपरकैट

2
वहाँ निश्चित रूप से कुछ है कि comitee द्वारा आसानी से सुधार किया जा सकता है, यह अंत में सफेद पर काला कहना है कि है typeinfoकी name()चाहिए समारोह ऐसा नाम है जो प्रोग्रामर और नहीं कुछ अपरिभाषित द्वारा में टाइप किया गया था वापस जाएँ। और हमें एन्यूमरेटर के लिए एक स्ट्रिंगर भी दें। यह वास्तव में क्रमांकन / deserialization, कारखानों को बनाने में मदद करने आदि के लिए महत्वपूर्ण है
v.oddou

38

परावर्तन के लिए कुछ मेटाडेटा के बारे में आवश्यकता होती है जो कहीं न कहीं जमा हो सकते हैं। चूंकि C ++ देशी मशीन कोड का संकलन करता है और अनुकूलन के कारण भारी परिवर्तन से गुजरता है, इसलिए आवेदन का उच्च स्तर का दृश्य संकलन की प्रक्रिया में बहुत अधिक खो जाता है, परिणामस्वरूप, उन्हें रन टाइम पर क्वेरी करना संभव नहीं होगा। जावा और .NET वर्चुअल मशीनों के लिए बाइनरी कोड में बहुत उच्च स्तर के प्रतिनिधित्व का उपयोग करते हैं जो इस स्तर के प्रतिबिंब को संभव बनाता है। कुछ सी ++ कार्यान्वयन में, हालांकि, रन टाइम टाइप इनफॉर्मेशन (आरटीटीआई) नामक कुछ है जिसे प्रतिबिंब का एक छीन लिया गया संस्करण माना जा सकता है।


15
RTTI C ++ मानक में है।
डैनियल ईयरविकर

1
लेकिन सभी C ++ कार्यान्वयन मानक नहीं हैं। मैंने ऐसे कार्यान्वयन देखे हैं जो RTTI का समर्थन नहीं करते हैं।
मेहरदाद अफश्री

3
और आरटीटीआई का समर्थन करने वाले अधिकांश कार्यान्वयन भी संकलक विकल्पों के माध्यम से इसे बंद करने का समर्थन करते हैं।
माइकल कोहेन

21

सभी भाषाओं को हर दूसरी भाषा की हर विशेषता को शामिल करने की कोशिश नहीं करनी चाहिए।

सी ++ अनिवार्य रूप से एक बहुत, बहुत परिष्कृत मैक्रो असेम्बलर है। यह (# पारंपरिक अर्थ में) C #, Java, ऑब्जेक्टिव-सी, स्मॉलटाक, आदि जैसी उच्च स्तरीय भाषा नहीं है।

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

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

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

सी #, जावा, ऑब्जेक्टिव-सी सभी को अपने निष्पादन का समर्थन करने के लिए बहुत बड़े, समृद्ध क्रम प्रणाली की आवश्यकता होती है। उस रनटाइम को सिस्टम में पहुंचाया जाना चाहिए - आपके सॉफ़्टवेयर के संचालन का समर्थन करने के लिए पूर्वस्थापित। और उस प्लेटफॉर्म पर काम करने के लिए SOME OTHER LANGUAGE द्वारा अनुकूलित विभिन्न लक्ष्य प्रणालियों के लिए उस परत को बनाए रखना पड़ता है। और वह मध्य परत - मेजबान ओएस और आपके कोड के बीच अनुकूली परत - रनटाइम, लगभग हमेशा C या C ++ जैसी भाषा में लिखा जाता है, जहां दक्षता # 1 है, जहां समझदारी से सॉफ्टवेयर और हार्डवेयर के बीच सटीक बातचीत अच्छी तरह से हो सकती है अधिकतम लाभ के लिए समझा, और हेरफेर किया।

मैं स्मॉलटाक, ऑब्जेक्टिव-सी से प्यार करता हूं, और प्रतिबिंब, मेटा-डेटा, कचरा संग्रह, आदि के साथ एक समृद्ध रनटाइम सिस्टम होने के कारण इन सुविधाओं का लाभ उठाने के लिए अद्भुत कोड लिखा जा सकता है! लेकिन यह केवल स्टैक पर एक उच्च परत है, एक परत जिसे निचली परतों पर आराम करना चाहिए, जो खुद को अंततः ओएस और हार्डवेयर पर बैठना होगा। और हमें हमेशा एक ऐसी भाषा की आवश्यकता होगी जो उस परत के निर्माण के लिए सबसे उपयुक्त हो: C ++ / C / Assembler।

परिशिष्ट: C ++ 11/14 उच्च स्तरीय सार और प्रणालियों का समर्थन करने के लिए C ++ क्षमता का विस्तार करने के लिए जारी है। थ्रेडिंग, सिंक्रोनाइज़ेशन, सटीक मेमोरी मॉडल, अधिक सटीक अमूर्त मशीन परिभाषाएँ C ++ डेवलपर्स को कई उच्च-स्तरीय अमूर्तताओं को प्राप्त करने में सक्षम कर रही हैं, जिनमें से कुछ उच्च-स्तरीय भाषाओं में केवल अनन्य डोमेन ओवर होते थे, जबकि करीब-करीब प्रदान करना जारी रहता है। धातु का प्रदर्शन और उत्कृष्ट भविष्यवाणी (यानी न्यूनतम रनटाइम सबसिस्टम)। शायद सी + + के भविष्य के संशोधन में प्रतिबिंब सुविधाओं को चुनिंदा रूप से सक्षम किया जाएगा, जो लोग इसे चाहते हैं - या शायद एक पुस्तकालय ऐसी रनटाइम सेवाएं प्रदान करेगा (शायद अब एक है, या एक को बढ़ावा देने की शुरुआत?)।


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

यह एक अंतर के बिना भेद है। क्या फर्क पड़ता है, जब अंत में, रनटाइम सबसिस्टम जो ऑब्जेक्टिव-सी का उपयोग करता है, वह वास्तव में ऑब्जेक्टिव-सी में नहीं लिखा जाता है, बल्कि सी में होता है?
मोर्दकै

3
मुझे माफ कर दो; लेकिन जब तक आप इसे ठीक से लिंक करते हैं, तब तक आप C में एक ऑब्जेक्टिव-सी प्रोग्राम को संकलित कर सकते हैं, वास्तव में मैंने इसे यहाँ किया था: stackoverflow.com/a/10290255/427309 । आपका पूरा उपरोक्त कथन गलत है। रनटाइम सी के माध्यम से पूरी तरह से सुलभ है, और इसकी एक चीज जो इसे इतनी शक्तिशाली गतिशील भाषा बनाती है।
रिचर्ड जे। रॉस III

1
"सी रनटाइम" सी मानक पुस्तकालय के लिए कोड युक्त एक गतिशील पुस्तकालय है। "C ++ रनटाइम" के लिए भी। यह ऑब्जेक्टिव-सी जैसे रनटाइम सिस्टम से काफी अलग है। इसके अलावा ... जब मुझे लगता है कि आप तकनीकी रूप से C में ऑब्जेक्टिव-सी रनटाइम का उपयोग कर सकते हैं, तो यह अभी भी एक सी प्रोग्राम है जो ऑब्जेक्टिव-सी रनटाइम का उपयोग करता है - आप सी में वास्तविक उद्देश्य-सी प्रोग्राम को संकलित नहीं कर सकते
celticminstost

2
सी एक स्मृति मॉडल ++ 11 होने + एटोमिक्स यह बनाता है और अधिक एक पोर्टेबल कोडांतरक की तरह। वे उच्च-स्तरीय चीजें नहीं हैं, वे निम्न स्तर की चीजें हैं जिन्हें C ++ में पहले के लिए पोर्टेबल समर्थन की कमी थी। लेकिन C ++ में UB की मात्रा यदि आप कुछ भी गलत करते हैं, तो यह VM- आधारित भाषाओं जैसे कि Java, और किसी भी विशिष्ट असेंबली भाषा के विपरीत बनाता है। उदाहरण के लिए हस्ताक्षरित-अतिप्रवाह C ++ स्रोत में पूरी तरह से यूबी है और संकलक उस तथ्य के आधार पर अनुकूलन कर सकता है, भले ही वह x86 कहने के लिए संकलित कर रहा हो, लेकिन लगभग सभी प्लेटफार्मों पर asm में यह बस चारों ओर लपेटेगा। आधुनिक सी ++ एक पोर्टेबल विधानसभा भाषा से बहुत दूर है।
पीटर कॉर्ड्स

11

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


6
इसके अलावा स्ट्रॉस्ट्रुप द्वारा सी ++ का डिजाइन और विकास
जेम्स हॉपकिन

9

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

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

लेकिन आप भाषा के बाहर कदम रख सकते हैं और पूर्ण प्रतिबिंब क्षमता प्राप्त कर सकते हैं । सी में प्रतिबिंब पर एक और ढेर अतिप्रवाह चर्चा का उत्तर इस पर चर्चा करता है


7

प्रतिबिंब पहले सी + + में लागू किया जा सकता है।

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

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


3
और आप प्रतीकों को शिप नहीं करते हैं क्योंकि यह आपके ग्राहकों / प्रतियोगियों को आपके कोड को देखने की अनुमति देगा ... यह अक्सर एक बुरी बात मानी जाती है।
gbjbaanb

आप सही कह रहे हैं, हालांकि कोड एक्सपोज़र की समस्या के बारे में भी मैंने ऐसा नहीं किया :)
०१'०

6

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


1
मुझे समझ में नहीं आता है कि कंपाइलर का आक्रामक अनुकूलन एक मजबूत बिंदु कैसे है। क्या आप विस्तार से समझा सकते हैं? यदि लिंकर डुप्लिकेट इनलाइन-फ़ंक्शन परिभाषाओं को हटा सकता है, तो डुप्लिकेट प्रतिबिंब जानकारी के साथ समस्या क्या है? क्या डिबगर्स के लिए, वैसे भी ऑब्जेक्ट फ़ाइलों में प्रतीक जानकारी जोड़ी नहीं गई है?
रोब कैनेडी

1
समस्या यह है कि आपकी प्रतिबिंब जानकारी अमान्य हो सकती है। यदि संकलक आपकी कक्षा की 80% परिभाषाओं को समाप्त कर देता है, तो आपका प्रतिबिंब मेटाडेटा क्या कहने जा रहा है? C # और Java में, भाषा गारंटी देती है कि यदि आप किसी वर्ग को परिभाषित करते हैं, तो वह परिभाषित रहता है। C ++ कंपाइलर को इसे ऑप्टिमाइज़ करने देता है।
जुलफ ११’०

1
@ रोब, अनुकूलन एक और बिंदु हैं, जो कई वर्गों की जटिलता से बंधा नहीं है। @ Jalf की टिप्पणी (और उसका उत्तर) देखें कि मेरा क्या मतलब है।
जोहान्स शाउब -

4
यदि मैं तत्काल <t> प्रतिबिंबित करता हूं, तो टी की किसी भी जानकारी को दूर न फेंके। यह एक अनसुलझी समस्या की तरह प्रतीत नहीं होता है।
जोसफ गार्विन

3

C ++ में परावर्तन का उपयोग करने के लिए बहुत सारे मामले हैं जिन्हें टेम्पलेट मेटा-प्रोग्रामिंग जैसे संकलित समय निर्माणों का उपयोग करके पर्याप्त रूप से संबोधित नहीं किया जा सकता है।

N3340 C ++ में प्रतिबिंब पेश करने के तरीके के रूप में समृद्ध बिंदुओं का प्रस्ताव करता है। जब तक आप इसका उपयोग नहीं करते, तब तक अन्य चीजों के बीच यह सुविधा के लिए भुगतान नहीं करने के मुद्दे को संबोधित करता है।


2

एलिस्टेयर कॉकबर्न के अनुसार, चिंतनशील वातावरण में उपप्रकार की गारंटी नहीं दी जा सकती

प्रतिबिंब टाइपिंग सिस्टम के लिए प्रतिबिंब अधिक प्रासंगिक है। C ++ में, आप जानते हैं कि आपको किस प्रकार का मिला है और आप जानते हैं कि आप इसके साथ क्या कर सकते हैं।


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

2

परावर्तन निर्देश की तरह, परावर्तन वैकल्पिक हो सकता है। कुछ इस तरह

#pragma enable reflection

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


2

यदि C ++ हो सकता है:

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

आज के वेब और डेटाबेस अनुप्रयोगों (सभी ओर्म्स, मैसेजिंग मेकेनिज्म, xml / json parsers, data serialization, आदि) में प्रचलित है जो टाइपलेस डेटा प्रोसेसिंग के क्रुज़ पर पुस्तकालयों का उपयोग करने के लिए बहुत आसान बनाने के लिए पर्याप्त होगा।

उदाहरण के लिए, Q_PROPERTYमैक्रो (क्यूटी फ्रेमवर्क का हिस्सा) द्वारा समर्थित बुनियादी जानकारी http://qt.nokia.com/doc/4.5/properties.html ने वर्ग विधियों और ई को कवर करने के लिए विस्तार किया) - C ++ और के लिए असाधारण लाभकारी होगा सामान्य तौर पर सॉफ्टवेयर समुदाय।

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


@Vlad: हाँ, अगर कोई भाषा में प्रतिबिंब का समर्थन करता है, तो आपको भाषा में प्रतिबिंब मिलता है। यह केवल तब होने की संभावना है जब भाषा समिति इसे कम करती है, और मुझे लगता है कि उनके पास 2011 तक नहीं है, और मुझे संदेह है कि 2020 ईस्वी से पहले एक और सी ++ मानक होगा। तो, अच्छा लगा। इस बीच, यदि आप प्रगति करना चाहते हैं तो आपको C ++ से बाहर कदम रखना होगा।
इरा बैक्सटर


0

C ++ में प्रतिबिंब, मेरा मानना ​​है कि महत्वपूर्ण है यदि C ++ को डेटाबेस एक्सेस, वेब सत्र हैंडलिंग / http और GUI विकास के लिए भाषा के रूप में उपयोग किया जाना है। प्रतिबिंब की कमी ORMs (हाइबरनेट या LINQ की तरह), XML और JSON पार्सर्स को रोकता है जो कक्षाओं, डेटा क्रमांकन और कई अन्य थिंकिंग (जहां शुरू में टाइपलेस डेटा का उपयोग एक वर्ग का उदाहरण बनाने के लिए किया जाता है) को रोकता है।

निर्माण प्रक्रिया के दौरान एक सॉफ़्टवेयर डेवलपर के लिए उपलब्ध एक संकलन समय स्विच का उपयोग इस 'आप जो आप उपयोग करते हैं उसके लिए भुगतान करते हैं' को खत्म करने के लिए किया जा सकता है।

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

न तो बूस्ट सीरियलाइज़ेशन और न ही अन्य तंत्र वास्तव में प्रतिबिंब को हल कर रहे हैं - यह कंपाइलर द्वारा किया जाना चाहिए - और एक बार जब यह C ++ हो जाता है तो इसे फिर से स्कूलों में खरीदा जाएगा और सॉफ्टवेयर में उपयोग किया जाएगा जो डेटा प्रोसेसिंग से संबंधित हैं

मेरे लिए यह अंक # 1 (और भोले थ्रेडिंग प्राइमेटिक्स # 2 मुद्दा है)।


4
किसने कहा कि C ++ को DB Access, Web session hnadling या gui dev के लिए एक भाषा के रूप में उपयोग किया जाना है? उस तरह के सामान के लिए उपयोग करने के लिए बहुत बेहतर भाषाएं हैं। और एक संकलन-समय स्विच समस्या का समाधान नहीं करेगा। आमतौर पर, प्रतिबिंब को सक्षम या अक्षम करने का निर्णय प्रति-फ़ाइल के आधार पर नहीं होगा। यदि यह व्यक्तिगत प्रकारों पर सक्षम किया जा सकता है तो यह काम कर सकता है। यदि प्रोग्रामर एक प्रकार को परिभाषित करते समय एक विशेषता या समान के साथ निर्दिष्ट कर सकता है, तो इसके लिए मेटाडेटा प्रतिबिंब होना चाहिए या नहीं। लेकिन एक वैश्विक स्विच? आप केवल 10% को सरल बनाने के लिए lnaguage के 90% को अपंग करेंगे।
jalf

फिर, अगर मुझे एक ऐसा प्रोग्राम चाहिए जो क्रॉस-प्लेटफ़ॉर्म और एक गुई तक पहुंच सके, तो मुझे क्या उपयोग करना चाहिए? अनम्य जावा स्विंग? विंडोज़ केवल C #? लेकिन सच कहा जाना चाहिए, और सच्चाई यह है कि निष्पादन योग्य कोड में बहुत सारे प्रोग्राम हैं, और एक गुई इंटरफ़ेस और डेटाबेस तक पहुंच प्रदान करते हैं, इसलिए उन्हें कुछ डेटाबेस और गुई समर्थन का उपयोग करना चाहिए ... और वे ' क्यू का उपयोग कर टी। (इसे MT (मॉन्स्टर टूलकिट) नाम दिया जाना चाहिए था)
Coyote21

1
@ Coyote21: C # केवल वर्षों के लिए Windows नहीं रहा है। (हालांकि मैं मोनो का प्रशंसक नहीं हूं, यह अधिकांश सामानों के लिए पर्याप्त रूप से काम करता है।) और स्विंग केवल जावा के लिए जीयूआई टूलकिट नहीं है। सच कहा जाए, तो या तो एक बेहतर विकल्प होगा यदि आप क्रॉस-प्लेटफॉर्म चाहते हैं। यदि आप कुछ भी गैर-तुच्छ कर रहे हैं तो C ++ बहुत ही हमेशा प्लेटफ़ॉर्म-विशिष्ट भागों में है।
cHao

कोई कारण नहीं है कि आपको ओआरएम के लिए प्रतिबिंब की आवश्यकता क्यों है। आप सभी को टेम्पलेट के साथ प्राप्त कर सकते हैं। C ++ के लिए ORM प्रदान करने वाले चौखटे का क्षेत्र गुच्छा।
MrFox

0

यह मूल रूप से है क्योंकि यह एक "वैकल्पिक अतिरिक्त" है। बहुत से लोग जावा और सी # जैसी भाषाओं पर C ++ चुनते हैं ताकि उनका कंपाइलर आउटपुट पर अधिक नियंत्रण हो, जैसे कि एक छोटा और / या तेज प्रोग्राम।

आप प्रतिबिंब जोड़ना चाहते हैं तो देखते हैं विभिन्न समाधान उपलब्ध

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.