रन-टाइम प्रकार की जानकारी
कंप्यूटर प्रोग्रामिंग में, रन-टाइम प्रकार की जानकारी या रन-टाइम प्रकार की पहचान (आरटीटीआई)[1] कुछ प्रोग्रामिंग भाषाओं की एक विशेषता है (जैसे C++,[2] वस्तु पास्कल, और एडा (प्रोग्रामिंग भाषा)[3]) जो रन टाइम (प्रोग्राम जीवनचक्र चरण) पर किसी वस्तु के डेटा प्रकार के बारे में जानकारी को उजागर करता है। रन-टाइम प्रकार की जानकारी सभी प्रकारों के लिए या केवल उन प्रकारों के लिए उपलब्ध हो सकती है जिनके पास यह स्पष्ट रूप से है (जैसा कि Ada के मामले में है)। रन-टाइम प्रकार की जानकारी एक अधिक सामान्य अवधारणा का विशेषज्ञता है जिसे टाइप आत्मनिरीक्षण कहा जाता है।
मूल सी ++ डिज़ाइन में, बज़्ने स्ट्रॉस्ट्रुप ने रन-टाइम प्रकार की जानकारी शामिल नहीं की, क्योंकि उन्होंने सोचा था कि इस तंत्र का अक्सर दुरुपयोग किया जाता था।[4]
सिंहावलोकन
सी ++ में, आरटीटीआई का उपयोग सुरक्षित प्रकार के रूपांतरण करने के लिए किया जा सकता है dynamic_cast<>
ऑपरेटर, और रनटाइम पर प्रकार की जानकारी में हेरफेर करने के लिए, typeid
ऑपरेटर और std::type_info
कक्षा। ऑब्जेक्ट पास्कल में, आरटीटीआई का उपयोग सुरक्षित टाइप कास्ट करने के लिए किया जा सकता है as
ऑपरेटर, उस वर्ग का परीक्षण करें जिससे कोई वस्तु संबंधित है is
ऑपरेटर, और इसमें निहित कक्षाओं के साथ रन टाइम पर प्रकार की जानकारी में हेरफेर करें RTTI
इकाई[5] (अर्थात कक्षाएं: TRttiContext, TRttiInstanceType, आदि)। Ada में, टैग किए गए प्रकार के ऑब्जेक्ट भी एक प्रकार का टैग संग्रहीत करते हैं, जो रनटाइम पर इन ऑब्जेक्ट के प्रकार की पहचान करने की अनुमति देता है। in
ई> ऑपरेटर का उपयोग रनटाइम पर परीक्षण करने के लिए किया जा सकता है, यदि कोई वस्तु एक विशिष्ट प्रकार की है और इसे सुरक्षित रूप से परिवर्तित किया जा सकता है।[6]
आरटीटीआई केवल उन कक्षाओं के लिए उपलब्ध है जो बहुरूपता (कंप्यूटर विज्ञान) हैं, जिसका अर्थ है कि उनके पास कम से कम एक आभासी विधि है। व्यवहार में, यह एक सीमा नहीं है क्योंकि बेस क्लास में आभासी विध्वंसक होना चाहिए ताकि बेस पॉइंटर से हटाए जाने पर व्युत्पन्न कक्षाओं की वस्तुओं को उचित सफाई करने की अनुमति मिल सके।
कुछ कंपाइलर्स में आरटीटीआई को अक्षम करने के लिए झंडे होते हैं। इन झंडों का उपयोग करने से एप्लिकेशन का समग्र आकार कम हो सकता है, जो सीमित मात्रा में मेमोरी वाले सिस्टम को लक्षित करते समय उन्हें विशेष रूप से उपयोगी बनाता है।[7]
== सी ++ - टाइपिड == typeid
ई> कीवर्ड (कंप्यूटिंग) का उपयोग रन टाइम (प्रोग्राम जीवनचक्र चरण) में किसी वस्तु (कंप्यूटर विज्ञान) के वर्ग (कंप्यूटर विज्ञान) को निर्धारित करने के लिए किया जाता है। यह एक संदर्भ (सी ++) देता है std::type_info
ऑब्जेक्ट, जो प्रोग्राम के अंत तक मौजूद रहता है।[8] का उपयोग typeid
, एक गैर-बहुरूपी संदर्भ में, अक्सर अधिक पसंद किया जाता है dynamic_cast<class_type>
ऐसी स्थितियों में जहां सिर्फ कक्षा की जानकारी की जरूरत होती है, क्योंकि typeid
हमेशा एक स्थिर समय होता है|निरंतर-समय की प्रक्रिया, जबकि dynamic_cast
रनटाइम पर इसके तर्क के वर्ग व्युत्पत्ति जाली को पार करने की आवश्यकता हो सकती है।[citation needed] लौटी हुई वस्तु के कुछ पहलू कार्यान्वयन-परिभाषित हैं, जैसे std::type_info::name()
, और सुसंगत होने के लिए सभी कंपाइलरों पर भरोसा नहीं किया जा सकता है।
वर्ग की वस्तुएँ std::bad_typeid
जब अभिव्यक्ति के लिए फेंक दिया जाता है typeid
यूनरी * ऑपरेटर को नल पॉइंटर पर लगाने का नतीजा है। क्या अन्य अशक्त संदर्भ तर्कों के लिए एक अपवाद फेंका गया है, कार्यान्वयन-निर्भर है। दूसरे शब्दों में, अपवाद की गारंटी के लिए, अभिव्यक्ति को रूप लेना चाहिए typeid(*p)
कहाँ p
कोई अभिव्यक्ति है जिसके परिणामस्वरूप शून्य सूचक होता है।
उदाहरण
<वाक्यविन्यास लैंग = सीपीपी>
- शामिल <iostream>
- शामिल <typeinfo>
वर्ग व्यक्ति { जनता:
आभासी ~ व्यक्ति () = डिफ़ॉल्ट;
};
वर्ग कर्मचारी: सार्वजनिक व्यक्ति {};
मुख्य प्रवेश बिंदु() {
व्यक्ति व्यक्ति; कर्मचारी कर्मचारी; व्यक्ति * पीटीआर = और कर्मचारी; व्यक्ति और संदर्भ = कर्मचारी; // टाइपिड :: नाम द्वारा लौटाई गई स्ट्रिंग कार्यान्वयन-परिभाषित है। एसटीडी :: अदालत << टाइपिड (व्यक्ति)। नाम () << एसटीडी :: एंडल; // व्यक्ति (सांख्यिकीय रूप से संकलन-समय पर जाना जाता है)। एसटीडी :: अदालत << टाइपिड (कर्मचारी) .नाम () << एसटीडी :: एंडल; // कर्मचारी (सांख्यिकीय रूप से संकलन-समय पर जाना जाता है)। एसटीडी :: अदालत << टाइपिड (पीआरटी) .नाम () << एसटीडी :: एंडल; // व्यक्ति * (सांख्यिकीय रूप से संकलन-समय पर जाना जाता है)। std::cout << typeid(*ptr).name() << एसटीडी :: एंडल; // कर्मचारी (रन-टाइम पर गतिशील रूप से देखा // क्योंकि यह a का dereference है // एक बहुरूपी वर्ग के लिए सूचक)। एसटीडी :: अदालत << टाइपिड (रेफरी)। नाम () << एसटीडी :: एंडल; // कर्मचारी (संदर्भ बहुरूपी भी हो सकते हैं)
व्यक्ति * पी = नलप्टर; कोशिश { टाइपिड (* पी); // अपरिभाषित व्यवहार नहीं; एसटीडी फेंकता है :: bad_typeid। } पकड़ना (...) { }
व्यक्ति और p_ref = *p; // अपरिभाषित व्यवहार: dereferencing null टाइपिड (p_ref); // एसटीडी फेंकने के लिए आवश्यकताओं को पूरा नहीं करता :: bad_typeid // क्योंकि टाइपिड के लिए अभिव्यक्ति परिणाम नहीं है // यूनरी * ऑपरेटर को लागू करने का।
} </वाक्यविन्यास हाइलाइट> आउटपुट (सटीक आउटपुट सिस्टम और कंपाइलर द्वारा भिन्न होता है):
व्यक्ति कर्मचारी व्यक्ति* कर्मचारी कर्मचारी
== सी ++ - डायनेमिक_कास्ट और जावा कास्ट == dynamic_cast
C++ में e> ऑपरेटर का उपयोग वर्ग पदानुक्रम में अधिक विशिष्ट प्रकार के संदर्भ या सूचक को डाउनकास्टिंग करने के लिए किया जाता है। से भिन्न static_cast
, का लक्ष्य है dynamic_cast
कक्षा (कंप्यूटर प्रोग्रामिंग) के लिए एक सूचक (कंप्यूटर प्रोग्रामिंग) या संदर्भ (कंप्यूटर विज्ञान) होना चाहिए। भिन्न static_cast
और सी (प्रोग्रामिंग भाषा) | सी-शैली टाइपकास्ट (जहां संकलन के दौरान टाइप चेक किया जाता है), रन टाइम (प्रोग्राम लाइफसाइकिल चरण) पर एक प्रकार की सुरक्षा जांच की जाती है। यदि प्रकार संगत नहीं हैं, तो एक अपवाद हैंडलिंग फेंक दी जाएगी (संदर्भ (सी ++) से निपटने पर) या एक शून्य सूचक लौटाया जाएगा (पॉइंटर (कंप्यूटर प्रोग्रामिंग) # सी और सी ++ से निपटने पर)।
एक जावा (प्रोग्रामिंग भाषा) टाइपकास्ट समान व्यवहार करता है; यदि डाली जा रही वस्तु वास्तव में लक्ष्य प्रकार का एक उदाहरण नहीं है, और भाषा-परिभाषित विधि द्वारा एक में परिवर्तित नहीं किया जा सकता है, तो इसका एक उदाहरण java.lang.ClassCastException
फेंक दिया जाएगा।[9]
उदाहरण
मान लीजिए कि कुछ उपनेमका प्रकार का एक वस्तु (कंप्यूटर विज्ञान) लेता है A
इसके तर्क के रूप में, और कुछ अतिरिक्त ऑपरेशन करने की इच्छा रखता है यदि पास की गई वस्तु का एक उदाहरण है B
, का एक उपवर्ग (कंप्यूटर विज्ञान)। A
. यह प्रयोग करके पूरा किया जा सकता है dynamic_cast
निम्नलिखित नुसार।
<वाक्यविन्यास लैंग = सीपीपी>
- शामिल <सरणी>
- शामिल <iostream>
- शामिल <मेमोरी>
- शामिल <typeinfo>
नेमस्पेस एसटीडी का उपयोग करना;
एक कक्षा { जनता:
// चूंकि आरटीटीआई वर्चुअल मेथड टेबल में शामिल है, वहां पर होना चाहिए // कम से कम एक वर्चुअल फ़ंक्शन। आभासी ~ ए () = डिफ़ॉल्ट;
शून्य विधि विशिष्ट ToA () { cout << A के लिए विशिष्ट विधि को लागू किया गया था << endl; }
};
कक्षा बी: सार्वजनिक ए { जनता:
शून्य विधि विशिष्ट ToB () { cout << B के लिए विशिष्ट विधि लागू की गई थी << endl; }
};
शून्य MyFunction (ए और my_a) {
कोशिश { // कास्ट केवल बी प्रकार की वस्तुओं के लिए सफल होगा। बी और my_b = गतिशील_कास्ट <बी और> (my_a); my_b.MethodSpecificToB (); } कैच (कास्ट बैड_कास्ट एंड ई) { cerr << अपवाद << e.what () << फेंका गया। << एंडल; cerr << ऑब्जेक्ट प्रकार B << endl का नहीं है; }
}
मुख्य प्रवेश बिंदु() {
सरणी <unique_ptr <A>, 3> array_of_a; // बेस क्लास ए के लिए पॉइंटर्स की सरणी। array_of_a [0] = make_unique <बी> (); // पॉइंटर टू बी ऑब्जेक्ट। array_of_a [1] = make_unique <बी> (); // पॉइंटर टू बी ऑब्जेक्ट। array_of_a [2] = make_unique<A>(); // पॉइंटर टू ए ऑब्जेक्ट।
के लिए (int i = 0; i <3; ++i) MyFunction(*array_of_a[i]);
} </वाक्यविन्यास हाइलाइट>
कंसोल आउटपुट:
बी के लिए विशिष्ट विधि लागू की गई थी बी के लिए विशिष्ट विधि लागू की गई थी अपवाद एसटीडी :: bad_cast फेंका गया। वस्तु प्रकार बी की नहीं है
का एक समान संस्करण MyFunction
संदर्भ (सी ++) के बजाय सूचक (कंप्यूटर प्रोग्रामिंग) के साथ लिखा जा सकता है:
<वाक्यविन्यास लैंग = सीपीपी> शून्य MyFunction (ए * my_a) {
बी * my_b = गतिशील_कास्ट <बी *> (my_a);
अगर (my_b! = nullptr) my_b-> methodSpecificToB (); अन्य एसटीडी :: सेर << वस्तु बी प्रकार नहीं है << एसटीडी :: एंडएल;
} </वाक्यविन्यास हाइलाइट>
डेल्फी/ऑब्जेक्ट पास्कल
ऑब्जेक्ट पास्कल में, ऑपरेटर is
रन टाइम (प्रोग्राम लाइफसाइकिल चरण) पर कक्षा के प्रकार की जांच के लिए प्रयोग किया जाता है। यह किसी दिए गए वर्ग के लिए किसी ऑब्जेक्ट से संबंधित परीक्षण करता है, जिसमें विरासत पदानुक्रम पेड़ में मौजूद व्यक्तिगत पूर्वजों के वर्ग शामिल हैं (उदाहरण के लिए बटन 1 एक टीबटन वर्ग है जिसमें पूर्वज हैं: TWinControl → TControl → TComponent → TPersistent → TObject, जहां बाद वाला पूर्वज है सभी वर्गों के)। परिचालक as
इसका उपयोग तब किया जाता है जब किसी वस्तु को रन टाइम पर व्यवहार करने की आवश्यकता होती है जैसे कि वह पूर्वज वर्ग से संबंधित हो।
आरटीटीआई इकाई का उपयोग रन टाइम पर वस्तु प्रकार की जानकारी में हेरफेर करने के लिए किया जाता है। इस इकाई में वर्गों का एक सेट है जो आपको अनुमति देता है: किसी वस्तु के वर्ग और उसके पूर्वजों, गुणों, विधियों और घटनाओं के बारे में जानकारी प्राप्त करें, गुण मूल्यों और कॉल विधियों को बदलें। निम्न उदाहरण आरटीटीआई मॉड्यूल के उपयोग को उस वर्ग के बारे में जानकारी प्राप्त करने के लिए दिखाता है जिससे कोई वस्तु संबंधित है, इसे बनाने और इसकी विधि को कॉल करने के लिए। उदाहरण मानता है कि TSubject वर्ग को SubjectUnit नामक इकाई में घोषित किया गया है। <syntaxhighlight lang= objectpascal > उपयोग
आरटीटीआई, सब्जेक्टयूनिट;
प्रक्रिया बिना प्रतिबिंब; वर
MySubject: TSubject;
शुरू
MySubject := TSubject.Create; कोशिश विषय।नमस्ते; आखिरकार विषय। मुक्त; अंत;
अंत;
प्रक्रिया के साथ प्रतिबिंब; वर
RttiContext: TRttiContext; आरटीटीआई टाइप: टीआरटीआई इंस्टेंस टाइप; विषय: टॉब्जेक्ट;
शुरू
RttiType := RttiContext.FindType('SubjectUnit.TSubject') TRttiInstanceType के रूप में; विषय:= RttiType.GetMethod('Create').Invoke(RttiType.MetaclassType, []).AsObject; कोशिश RttiType.GetMethod ('हैलो')। आह्वान (विषय, []); आखिरकार विषय। मुक्त; अंत;
अंत; </वाक्यविन्यास हाइलाइट>
यह भी देखें
- अनुमान टाइप करें
- आत्मनिरीक्षण टाइप करें
- के प्रकार
- प्रतिबिंब (कंप्यूटर विज्ञान)
- टेम्पलेट (सी ++)
संदर्भ
- ↑ Sun Microsystems (2000). "Runtime Type Identification". C++ Programming Guide. Oracle. Retrieved 16 April 2015.
- ↑ "Language support library [support.rtti]". eel.is. Retrieved 2021-07-13.
- ↑ "Object-oriented programming". learn.adacore.com. Retrieved 2021-07-13.
- ↑ Bjarne Stroustrup (March 1993). "A History of C++: 1979—1991" (PDF). Bjarne Stroustrup. p. 50. Retrieved 2009-05-18.
- ↑ "Working with RTTI - RAD Studio". docwiki.embarcadero.com. Retrieved 2021-06-06.
- ↑ English, John (2002-02-22). "Chapter 15". Ada 95: The Craft of Object-Oriented Programming. Retrieved 2021-07-13.
- ↑ "Avoiding RTTI, and support for -fno-rtti in Arm Compiler 6". Arm Developer. Retrieved 2021-07-13.
- ↑ C++ standard (ISO/IEC14882) section 5.2.8 [expr.typeid], 18.5.1 [lib.type.info] -- http://cs.nyu.edu/courses/fall11/CSCI-GA.2110-003/documents/c++2003std.pdf
- ↑ "ClassCastException (Java Platform SE 8 )".