2010-11-25 8 views
13

Ich habe ein Problem mit einer shared_ptr einer Basisklasse, ich kann nicht in der Lage sein, die Methoden der abgeleiteten Klasse aufrufen, wenn es Dereferenzierung. Ich glaube, Code wird ausführlicher als ich:boost :: shared_ptr und dynamische Besetzung

class Base : public boost::enable_shared_from_this<Base> 
{ 
    public: 
    typedef boost::shared_ptr<BabelNet> pointer; 
}; 

class Derived : public Base 
{ 
    public: 
    static pointer create() 
       { 
         return pointer(new Derived); 
       } 
    void    anyMethod() 
    { 
     Base::pointer foo = Derived::create(); 
     // I can't call any method of Derived with foo 
     // How can I manage to do this ? 
     // is dynamic_cast a valid answer ? 
     foo->derivedMethod(); // -> compilation fail 
    } 

}; 
+1

Es wäre hilfreich, wenn Ihr Beispiel kompilierbar wäre, natürlich mit der beanstandeten Zeile kommentiert. –

Antwort

18

siehe static_cast with boost::shared_ptr?

Sie dynamic_pointer_cast verwenden müssen Sie die entsprechende shared_ptr Instanzierung zu erhalten. (entspricht einem dynamic_cast)

+1

Warum nicht 'static_pointer_cast'? Ich schätze, das Beispiel ist nicht repräsentativ für den realen Code, aber das Beispiel benötigt keinen dynamischen Cast (weil das Objekt vom Zieltyp ist) und erlaubt keinen (weil keine der Klassen virtuelle Funktionen hat) . –

+0

Ich habe 'dynamic_pointer_cast' wegen des Titels des Posts geschrieben. Aber ja, in seinem Code wird ein 'static_pointer_cast' genügen. – lijie

+0

Richtig, dank dir habe ich einen interessanten Artikel gefunden: http://nealabq.com/blog/2008/11/26/pointer_cast/ wenn ich nur eine shared_ptr zu der derived_class verwende, kann ich sie als shared_ptr übergeben die Basisklasse, ordentlich. – HolyLa

1

Wenn derivedMethod nicht in Basisklasse (virtuell oder nicht) deklariert wird, dann ist es normal, dass die Kompilierung fehlschlagen würde. Das shared ptr kennt und verwendet die Basisklasse (über den Zeiger, den es enthält) und weiß nichts über die abgeleitete Klasse und ihre spezifischen Methoden.

+0

Wenn der Zeiger ein typedef der abgeleiteten Klasse war, konnte es so aktualisiert werden, dass eine externe Klasse nur über Base :: pointer wissen kann? – HolyLa

0

Ihr Code würde nicht einmal mit rohen Zeigern funktionieren.

Sie müssen entweder die derivedMethod() Methode sogar in der Basisklasse deklarieren oder einen Zeiger auf ein Derived Objekt haben.

4

Gemeinsamer Zeiger oder nicht, wenn Sie einen Zeiger auf eine Base haben, können Sie nur Elementfunktionen von Base aufrufen.

Wenn Sie wirklich dynamic_cast benötigen, können Sie dynamic_pointer_cast von boost verwenden, aber die Chancen sind, dass Sie nicht sollten. Denken Sie stattdessen an Ihr Design: Derived ist ein Base, und das ist eine extrem starke Beziehung, so denke sorgfältig über Base Schnittstelle und wenn der konkrete Typ wirklich bekannt sein muss.