2013-02-11 7 views
5

Meine Frage ist, wie kann ich auf das "obj" Mitglied zugreifen, wenn ich einen Zeiger auf die Basisklasse ("a") auf Kindklasse ("b ") Objekt? Ich weiß, dass Casting den Trick machen sollte, aber ich suche nach besseren Lösungen.Zugreifen auf untergeordnete Klassenmitglieder mit Zeiger auf eine Basis abstact Klasse

+0

Einige Kontext würde helfen. Warum willst du das tun? Wenn das Casting keine Option ist, müssen Sie in Ihrer abgeleiteten Klasse eine virtuelle Funktion überschreiben, die einen Verweis oder Zeiger auf dieses Member zurückgibt. Dies bricht jedoch im Allgemeinen die Einkapselung. Das bringt uns zurück zu dem Grund, warum Sie auf den abgeleiteten Klassenmember durch einen Zeiger auf die Basisklasse zugreifen möchten? – Void

+0

@Void wahrscheinlich hast du Recht, ich sollte das Design ändern. – user1873947

Antwort

7

Mit dem Operator dynamic_cast<> können Sie einen Zeiger auf a in einen Zeiger auf b konvertieren. Die Umwandlung wird nur gelingen, wenn der Laufzeittyp des Objekts zu spitz durch ptr ist b, und wird ein Null-Zeiger andernfalls zurückkehren, so dass Sie das Ergebnis nach der Konvertierung überprüfen müssen:

b* p = dynamic_cast<b*>(ptr); 
if (p != nullptr) 
{ 
    // It is safe to dereference p 
    p->foo(); 
} 

Wenn Sie garantieren können, dass Der Typ des Objekts, auf das ptr zeigt, ist b, aber in diesem Fall (da keine virtuelle Vererbung beteiligt ist) können Sie sogar static_cast<> verwenden, was mit weniger Aufwand verbunden ist, da es zur Kompilierungszeit ausgeführt wird.

b* p = static_cast<b*>(ptr); 
// You are assuming ptr points to an instance of b. If your assumption is 
// correct, dereferencing p is safe 
p->foo(); 
3

Sie müssen die Vererbungshierarchie ablegen. Ihr Fall ist für die Verwendung von dynamic_cast auf den entsprechenden Typ maßgeschneidert, da Sie damit typsicher einchecken können, wenn das Objekt, das Sie tatsächlich zu werfen versuchen, vom erwarteten Typ ist.

+0

Ich habe nicht an dynamic_cast gedacht, das sollte das Problem lösen, da es typsicher ist. – user1873947

1

In GCC und Clang (und in Visual Studio glaube ich) Sie auch folgenden syntaktischen Zucker

if (Base* x = dynamic_cast<Base*>(x)) { 
    // do something with \c x now that we know its defined  
} 

und in C++ 11 verwenden können, mit auto Typinferenz, noch schöner

if (auto x = dynamic_cast<Base*>(x)) { 
    // do something with \c x now that we know its defined  
} 

und schließlich, wenn wir nur zu lesenden Zugriff

if (const auto x = dynamic_cast<Base*>(x)) { 
    // read something from \c x now that we know its defined  
} 
01 einschränken möchten

Beachten Sie, dass dies den Bereich von x auf die Innenseite der If-Klausel (s) beschränkt, was oft bequemer ist, wenn wir mehrere aufeinander folgende dynamic_cast nacheinander unter Verwendung von if und else if durchführen.

Verwandte Themen