2010-10-05 9 views
6

से असर हैं, नीचे दिया गया कोड समस्या बताता है। वर्चुअल बेस क्लास ए के दो पॉइंटर्स वास्तव में एक ही ठोस कक्षा में पता लगाने के लिए same_sub_class भरें।सी ++ में जांचें कि बेस क्लास के दो उदाहरण एक ही उपclass

struct A { 
    ... 
}: 

struct B : public A { 
    ... 
}: 

struct C : public A { 
    ... 
} 


bool same_sub_class(A * a1, A * a2){ 
    // Fill this in to return true if a1 and a2 are 
    // of the same concrete class 
} 

संपादित करें:

जैसा कि मैंने अपने आवेदन को देखो मैं कुछ ऊपर से थोड़ा अलग की जरूरत है। मुझे उनके टाइप_आईडी द्वारा उदाहरणों को समूहित करने में सक्षम होना चाहिए।

एफवाईआई। मेरे पास एक मिनी प्रतीकात्मक अल्जीब्रा प्रणाली है ताकि मैनिप्लेशंस करने के लिए कभी-कभी वर्ग प्रकार को सॉर्ट करने और अभिव्यक्तियों को पुन: व्यवस्थित करने के लिए जानना महत्वपूर्ण है।

तो पॉइंटर्स के वेक्टर को उदाहरण के लिए उनके टाइप_आईडी द्वारा समूहित करने के लिए दिया गया है। मुझे या तो टाइप_आईडी हैश करने में सक्षम होना चाहिए या प्रत्येक वर्ग के लिए एक अद्वितीय पूर्णांक उत्पन्न करना होगा।

+1

लगता है कि आपको वास्तव में क्या चाहिए, प्रत्येक वर्ग पर एक स्थिर int है? –

उत्तर

17

आप RTTI का उपयोग कर सकते हैं, तो

typeid(*a1) == typeid(*a2) 

मुझे लगता है कि आप भी

#include <typeinfo> 

करने की जरूरत है और आप अपनी कक्षाओं में एक आभासी समारोह ताकि vtable मौजूद होना आवश्यक है - एक नाशक चाहिए ठीक करो

अद्यतन:

मुझे यकीन है कि मैं पूरी तरह से समझते हैं कि अपनी आवश्यकताओं के समूहीकरण के लिए कर रहे हैं नहीं कर रहा हूँ, लेकिन आप की कोशिश कर सकते हैं (आप नियतात्मक आदेश के कुछ प्रकार की जरूरत है क्या उप उपवर्गों के साथ उसका क्या होगा??) का उपयोग कर value या तो करने के लिए typeid ऑपरेटर से लौटे:

  • हैश स्ट्रिंग एक आदेश कसौटी के रूप में typeid(*ptr).name()
  • से लौटे उपयोग typeid(*a1).before(typeid(*a2))। हालांकि, रनों के बीच इसका कोई निर्धारण नहीं है।

आम तौर पर जब RTTI पर विचार, यह देखने के लिए कि इस के किसी भी बेहतर पूरा किया जा सकता एक अच्छा विचार अच्छी तरह से तैयार आभासी कार्यों का उपयोग कर (double dispatch उदाहरण के लिए,) है। हालांकि, मैं वास्तव में यह नहीं कह सकता कि आपके मामले में कोई अच्छा विकल्प है, क्योंकि मैं विनिर्देशों को समझ नहीं पा रहा हूं।

+1

आपको '' भी शामिल करना याद रखना होगा। –

+0

लेकिन 'ए' को पॉलिमॉर्फिक होना नहीं है ?? – liaK

+2

@liaK, हां, बेस क्लास में कम से कम एक वर्चुअल फ़ंक्शन होना चाहिए। – avakar

6
typeid(*a1) == typeid(*a2) 

अव्यवस्था नोट करें, यह महत्वपूर्ण है।

struct A{ 
... 
protected: 
enum TypeTag{B_TYPE, C_TYPE}; 
TypeTag typeTag; 
}; 

और फिर उपवर्गों की कंस्ट्रक्टर्स में:

+0

बेशक, परस्पर। –

2

आप अपनी खुद की प्रकार पहचानकर्ता बना सकता है

B::B() 
: typeTag(TypeTag::B_TYPE) 
{ 
... 
} 

C::C() 
: typeTag(TypeTag::C_TYPE) 
{ 
... 
} 
+0

टाइपटाग बेहतर निजी हो। Enum लेकिन परिवर्तनीय नहीं है। –

+0

@Manoj: मैं असहमत हूं। टाइपटाग को सुब्बास कन्स्ट्रक्टर में शुरू किया गया है, इसलिए यह बेस क्लास का निजी सदस्य नहीं हो सकता है। – Adesit

+0

@Adesit: typeTag संरक्षित होना चाहिए। लेकिन यह तंत्र सही नहीं है, क्योंकि नए वंशज को जोड़ने पर हमें enum के नए सदस्य को जोड़ने की जरूरत है। ओडेसा का सबसे अच्छा संबंध :) – zabulus

0

वहाँ सी में एक फीचर ++ जो आप के लिए अनुमति देता RTTI (क्रम प्रकार की जानकारी) कहा जाता है ऐसी चीजें करो

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

0

एक चाल है कि या RTTI के साथ काम नहीं हो सकता है, अपने संकलक पर निर्भर करता है, है

const type_info &a1_type_info= typeid(*a1); 
const type_info &a2_type_info= typeid(*a2); 

return &a1_type_info==&a2_type_info || a1_type_info==a2_type_info; 

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

1

वास्तव में इसके लिए काफी सरल उत्तर हैं। लेकिन इसमें प्रश्नों को थोड़ा स्पष्ट करना शामिल है।

(ए) अगर मैं एक unordered_set में typeinfo ऑब्जेक्ट्स स्टोर करना चाहता हूं तो मुझे क्या करने की ज़रूरत है?

typeinfo == और नाम() विधि का समर्थन करता है। नाम का उपयोग हैश और 0= समानता

(बी) यदि मैं typeinfo ऑब्जेक्ट्स को ऑर्डर_सेट (std :: set) में संग्रहीत करना चाहता हूं तो मुझे क्या करना होगा?

टाइपइन्फो == और पहले() विधि का समर्थन करता है। इन दो विधियों के लपेटने के साथ मैं तुलनात्मक फ़ंक्शन के लिए एक इंटरफ़ेस कार्यान्वित कर सकता हूं जो मुझे सख्त कमजोर आदेश देता है।

संबंधित मुद्दे