2013-06-20 11 views
5

I Klasse B haben, die von A. erbtÜberprüfen des Objekttypen in C++ 11

class A 
{ 
}; 

class B : public A 
{ 
}; 

Und ich habe drei Objekte.

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

Ich möchte, wenn ein Scheck Objekt vom Typ A ist, A2 ist Objekt vom Typ B (nicht A), und b Objekt vom Typ B.

habe ich versuchte, typisierte Vergleich, aber Es gibt mir keine richtige Antwort.

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 

Ich habe versucht, dynamische Casting, aber ich habe kompilieren Fehler.

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); 

Ich habe statische Casting verwendet, aber ich habe die Antwort falsch.

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 
} 

Wie kann ich den Objekttyp in C++11 korrekt identifizieren?

+0

'* a' ist vom Typ' A' und '* b' ist vom Typ' B' für ihre Deklaration. –

+0

Dynamic Cast funktioniert nur mit virtual, aber Ihr Code hat keine virtuelle Funktion. –

+0

Beste Minimallösung ähnlich wie Ihr Code: http://coliru.stacked-crooked.com/view?id=7150bf0db7988cf1d2988aba99c72392-3b440a87a52fe2ae7c853c82f4c5144f – chris

Antwort

10

Einige Klassen sind polymorph, einige nicht polymorph.

Eine polymorphe Klasse hat eine oder mehrere virtuelle Funktionen (möglicherweise geerbt), eine nicht-polymorphe Klasse hat keine virtuellen Funktionen.

Ihr A und B sind nicht-polymorph.

Eine polymorphe Version von A und B das Verhalten Sie wollen zeigen:

#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 
} 

Instanzen einer polymorphen Klasse speichert die dynamische Art ihres meist abgeleitete Objekts zur Laufzeit.

(In Ihrem Beispiel ist a2 vom Typ pointer-to-A, und ist in einem Objekt vom Typ A zeigt jedoch Dieses Objekt ist nur eine Basisklasse Subobjekt der meisten dervived Objekte vom Typ B. Was Sie erhalten möchten, ist die Art der meisten Objekt B abgeleitet wird, wenn a2 abfragt. Dazu geben Sie eine polymorphe Klasse benötigen.)

das ist, wie polymorphe Klassen dynamic_cast und typeid der am meisten abgeleitete Objekt unterstützen (wie auch virtuelle Funktion Versand).

Nicht polymorphe Klassen verfügen nicht über diese Informationen, daher können sie nur den zum Kompilierungszeitpunkt bekannten statischen Typ melden. Nicht-polymorphe Klassen sind kompakter und effizienter als polymorphe Klassen. Aus diesem Grund sind nicht alle C++ - Klassen polymorph. Die Sprache überlässt es dem Programmierer, den Kompromiss zwischen Leistung und Funktionalität zu wählen. Zum Beispiel:

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

Auf meinem System nicht-polymorphen Z ist sizeof(Z) == 4 bytes, gleiche wie ein int.

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

Jetzt, nachdem Sie Z polymorphe, sizeof(Z) == 16 bytes.So ist ein Array von Z jetzt 300% größer, weil jede Z Instanz ihre Typinformation zur Laufzeit speichern muss.

+1

http://stackoverflow.com/questions/17221668/why-do-we-need-to -use-virtual-a-default-statt-von-virtuell-a-in-c – prosseek

+2

@Sharth: Nein, [das stimmt nicht] (http://stackoverflow.com/a/17222286/560648); Sie bekommen es nicht in jedem Fall. –

+0

@LightnessRacesinOrbit, @prosseek: Danke für die Korrektur !. Ich hatte gedacht, dass dies einer der Hauptgründe für den Fall "= default" war. –