2016-05-12 12 views
3

Ich versuche, ein Basisklassenobjekt zu einem abgeleiteten Klassenobjekt mit dynamic_cast zu werfen, aber dynamic_cast gibt null zurück. Ist es möglich, mit dynamic_cast zu reduzieren?Downcasting mit dynamic_cast gibt null

struct A { 
    virtual ~A() {} 
}; 

struct B : A {}; 


int main() 
{ 
    A* a = new A(); 

    B* b = dynamic_cast<B*>(a); 
    if(b){ 
     std::cout << "b has value" << std::endl; 
    }else{ 
     std::cout << "no value" << std::endl; 
    } 
} 

Dieser Code gibt "keinen Wert" aus.

+0

FYI casting * down * die Vererbungskette wird Down Casting genannt. – NathanOliver

+2

Sie können kein B von einem A erhalten, was würde die Sprache tun, wenn z. B-Instanzen hatten mehr Datenelemente als A-Instanzen? –

+3

Sie können 'a' nicht auf' B * 'reduzieren, da es nicht auf ein' B' zeigt, sondern auf ein 'A':' A' ist kein 'B'. Sie könnten jedoch ein 'B *' in ein 'A *' umwandeln, weil das 'B *' auf ein B zeigt, das "A" ist (Definition der Vererbung) – KABoissonneault

Antwort

14

Da a auf A in der Tat zeigt, wird kein B, dann dynamic_cast wird fehlschlagen.

Ist es möglich, mit dynamic_cast zu senken?

Ja, Sie können z.B. wenn a Punkte B genau,

A* a = new B; 
B* b = dynamic_cast<B*>(a); 

http://en.cppreference.com/w/cpp/language/dynamic_cast

5) Siehe Wenn expression ein Zeiger oder eine Referenz auf eine polymorphe Typ Base und new_type ist ein Zeiger oder Verweis auf die Art, die einen Lauf Abgeleitet -Zeitüberprüfung wird durchgeführt:

a) Das am meisten abgeleitete Objekt, das durch Ausdruck gezeigt/identifiziert wurde, wird untersucht. Wenn in diesem Objekt der Ausdruck auf eine öffentliche Basis von Abgeleitet verweist und wenn nur ein Unterobjekt vom Abgeleiteten Typ von dem durch Ausdruck verwiesenen/identifizierten Unterobjekt abgeleitet wird, bezieht sich das Ergebnis der Umwandlungspunkte auf das abgeleitete Unterobjekt. (Dies wird als "gesenkten" bekannt.)

...

c) Andernfalls schlägt die Laufzeitprüfung. Wenn die dynamic_cast in Zeigern verwendet wird, wird der Nullzeigerwert vom Typ new_type zurückgegeben. Wenn es für Referenzen verwendet wurde, wird die Ausnahme std::bad_cast ausgelöst.

+0

Bin ich in der Lage, 'dynamic_cast' zu verwenden, wenn das Basisobjekt hat default ctor gelöscht und kann nur mit der statischen Funktion 'create' erstellt werden? – Herrgott

+0

@Herrgott Ja. 'dynamic_cast' arbeitet mit Zeigern und Referenzen, die keine Standardkonstruktoren der Basisklasse beinhalten. – songyuanyao

4

Das ist pro Design. dynamic_cast wird verwendet, wenn Sie testen möchten, ob ein Zeiger auf ein Basisklassenobjekt tatsächlich auf eine Unterklasse verweist oder nicht. Wenn es sich um ein Unterklassenobjekt handelt, gibt Ihnen dynamic_cast einen gültigen Zeiger, und wenn nicht, erhalten Sie nur nullptr.

Während Sie ein Klassenobjekt A erstellt haben und und A keine Unterklasse von B ist, hat dynamic_cast normalerweise einen Nullzeiger zurückgegeben.