2013-06-20 5 views
5

मैं वर्ग बी में ऑब्जेक्ट प्रकार है कि एसी ++ 11

class A 
{ 
}; 

class B : public A 
{ 
}; 

और मैं तीन वस्तुओं है से विरासत जाँच हो रही है।

A* a = new A(); 
A* a2 = new B(); 
B* b = new B(); 

मैं चाहते हैं अगर जांच एक ग्रुप ए की वस्तु है, a2 ग्रुप बी (नहीं ए) की वस्तु है, और ख प्रकार बी की वस्तु है

मैंने कोशिश की तुलना आपके द्वारा लिखा गया है, लेकिन यह मुझे सही जवाब नहीं देता है।

cout << (typeid(*a) == typeid(A)) << endl; // -> 1 
cout << (typeid(*a2) == typeid(A)) << endl; // -> 1 
cout << (typeid(*b) == typeid(A)) << endl; // -> 0 

cout << (typeid(*a) == typeid(B)) << endl; // -> 0 
cout << (typeid(*a2) == typeid(B)) << endl; // -> 0 
cout << (typeid(*b) == typeid(B)) << endl; // -> 1 

मैंने गतिशील कास्टिंग करने की कोशिश की, लेकिन मुझे संकलन त्रुटि मिली।

B* derived = dynamic_cast<B*>(a); 
if (derived) { 
    cout << "a is B"; 
} 
derived = dynamic_cast<B*>(a2); 
if (derived) { 
    cout << "a2 is B"; 
} 
derived = dynamic_cast<B*>(b); 
if (derived) { 
    cout << "b is B"; 
} 

typename.cpp: In function 'int main(int, char**)': 
typename.cpp:27:36: error: cannot dynamic_cast 'a' (of type 'class A*') to type 'class B*' (source type is not polymorphic) 
    B* derived = dynamic_cast<B*>(a); 
            ^
typename.cpp:31:34: error: cannot dynamic_cast 'a2' (of type 'class A*') to type 'class B*' (source type is not polymorphic) 
    derived = dynamic_cast<B*>(a2); 

मैंने स्थिर कास्टिंग का उपयोग किया, लेकिन मुझे जवाब गलत मिला।

B* derived = static_cast<B*>(a); 
if (derived) { 
    cout << "a is B"; // -> YES 
} 
derived = static_cast<B*>(a2); 
if (derived) { 
    cout << "a2 is B"; // -> YES 
} 
derived = dynamic_cast<B*>(b); 
if (derived) { 
    cout << "b is B"; // -> YES 
} 

कैसे मैं सही ढंग से C++11 में ऑब्जेक्ट प्रकार की पहचान कर सकते हैं?

+0

'* ए 'प्रकार' ए' और '* बी' प्रकार की घोषणा के अनुसार' बी' प्रकार है। –

+0

डायनामिक कास्ट केवल वर्चुअल के साथ काम करेगा लेकिन आपके कोड में कोई वर्चुअल फ़ंक्शन नहीं है। –

+0

आपके कोड के समान सर्वश्रेष्ठ न्यूनतम समाधान: http://coliru.stacked-crooked.com/view?id=7150bf0db7988cf1d2988aba99c72392-3b440a87a52fe2ae7c853c82f4c5144f – chris

उत्तर

10

कुछ कक्षाएं पॉलिमॉर्फिक हैं, कुछ गैर-पॉलिमॉर्फिक हैं।

एक पॉलिमॉर्फिक वर्ग में एक या अधिक वर्चुअल फ़ंक्शंस (संभवतः विरासत में) हैं, गैर-पॉलीमोर्फिक वर्ग में शून्य वर्चुअल फ़ंक्शन हैं।

आपका ए और बी गैर-पॉलिमॉर्फिक हैं।

ए और बी के एक बहुरूपी संस्करण व्यवहार आप चाहते हैं प्रदर्शन करेंगे:

#include <iostream> 
#include <typeinfo> 

using namespace std; 

struct A 
{ 
    virtual ~A() {}; // add virtual function 
}; 

class B : public A 
{ 
}; 

A* a = new A(); 
A* a2 = new B(); 
B* b = new B(); 

int main() 
{ 
    cout << (typeid(*a) == typeid(A)) << endl; // -> 1 
    cout << (typeid(*a2) == typeid(A)) << endl; // -> 0 <-- CHANGED 
    cout << (typeid(*b) == typeid(A)) << endl; // -> 0 

    cout << (typeid(*a) == typeid(B)) << endl; // -> 0 
    cout << (typeid(*a2) == typeid(B)) << endl; // -> 1 <-- CHANGED 
    cout << (typeid(*b) == typeid(B)) << endl; // -> 1 
} 

एक बहुरूपी वर्ग दुकान क्रम में अपने सबसे व्युत्पन्न वस्तु के गतिशील प्रकार के उदाहरण।

(अपने उदाहरण a2 में प्रकार सूचक करने वाली एक की है, और ग्रुप ए के किसी ऑब्जेक्ट पर इंगित कर रहा है, लेकिन इस ऑब्जेक्ट प्रकार बी के सबसे dervived वस्तु का केवल एक आधार वर्ग subobject है क्या आप प्राप्त करना चाहते हैं यह सबसे व्युत्पन्न वस्तु बी के प्रकार जब a2 क्वेरी करने है। इसके लिए आपको एक बहुरूपी वर्ग की जरूरत है।)

है कि कैसे बहुरूपी वर्गों का समर्थन dynamic_cast और सबसे व्युत्पन्न वस्तु की typeid (और साथ आभासी रूप में समारोह प्रेषण)।

गैर-पॉलिमॉर्फिक कक्षाओं में यह जानकारी नहीं है, इसलिए वे केवल संकलित समय पर ज्ञात स्थिर प्रकार की रिपोर्ट कर सकते हैं। गैर-पॉलिमॉर्फिक कक्षाएं अधिक कॉम्पैक्ट और कुशल होती हैं तो पॉलिमॉर्फिक कक्षाएं। यही कारण है कि सभी सी ++ कक्षाएं polymorphic नहीं हैं। प्रदर्शन और कार्यक्षमता के बीच व्यापार को चुनने के लिए भाषा प्रोग्रामर को छोड़ देती है। उदाहरण के लिए:

struct X { int x; }; 
struct Y : X {}; 
struct Z : Y {}; 

अपने सिस्टम गैर बहुरूपी Z पर sizeof(Z) == 4 bytes, एक int के समान है।

struct X { int x; virtual ~X() {}; }; 
struct Y : X {}; 
struct Z : Y {}; 

अब Z बहुरूपी, sizeof(Z) == 16 bytes करने के बाद।तो ज़ेड की एक सरणी अब 300% बड़ी है, क्योंकि प्रत्येक Z उदाहरण को रनटाइम पर अपनी प्रकार की जानकारी स्टोर करना होगा।

+1

http://stackoverflow.com/questions/17221668/why-do-we-need-to -उजुअल-वर्चुअल-ए-डिफॉल्ट-वर्चुअल-ए-इन-सी – prosseek

+2

@ शार्थ: नहीं, [यह सच नहीं है] (http://stackoverflow.com/a/17222286/560648); आप इसे _either_ मामले में नहीं मिला है। –

+0

@ लाइटनेसरेसेसिन ऑर्बिट, @prosseek: सुधार के लिए धन्यवाद! मैंने सोचा था कि 'डिफ़ॉल्ट 'मामले के मुख्य कारणों में से एक था। –