static_cast mit boost :: shared_ptr?

73

Was ist das Äquivalent von a static_castmit boost::shared_ptr?

Mit anderen Worten, wie muss ich Folgendes umschreiben?

Base* b = new Derived();
Derived* d = static_cast<Derived*>(b);

bei der Verwendung shared_ptr?

boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = ???
Frank
quelle
22
Sollte es nicht sein Base *b = new Derived();?
Legends2k

Antworten:

106

Verwendung boost::static_pointer_cast:

boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = boost::static_pointer_cast<Derived>(b);
Frank
quelle
Ich habe zuerst versucht, den Rohzeiger zu übertragen und neu zu verpacken, ohne etwas über static_pointer_cast zu wissen. Daher halte ich es für nützlich, diese Informationen über den Stapelüberlauf zu haben.
Frank
4
boost::static_pointer_cast<Derived>(b)könnte auch Baseimplizit verwendet werden.
dalle
5
Ich dachte nur, ich würde Ihnen mitteilen, dass Sie, wenn Sie dies verwenden und die abgeleitete Klasse nicht vollständig enthalten ist (dh nur vorwärts deklariert wurde), die sehr wenig hilfreiche "ungültige Typkonvertierung" erhalten: "Base *" in "Derived *" ". Es hat ziemlich lange gedauert, bis ich es herausgefunden habe :)
Jamie Cook
1
ist 'boost :: shared_ptr <Derived> d = boost :: static_pointer_cast <Derived> (b);' GÜLTIG? da b nur Speicher für die Basisklasse enthält - 'b (new Base ());'
Saskia
@Oleksandra, ja - aber es ist der gleiche Fehler wie in OP. Franks Beitrag zu diesem Zweck bearbeitet.
Peterchen
22

Es gibt drei Cast - Operatoren für intelligente Zeiger: static_pointer_cast, dynamic_pointer_cast, und const_pointer_cast. Sie befinden sich entweder im Namespace boost(bereitgestellt von <boost/shared_ptr.hpp>) oder im Namespace std::tr1(bereitgestellt von Boost oder von der TR1-Implementierung Ihres Compilers).

Michael Kristofik
quelle
3

Als Kommentar: Wenn Derived tatsächlich von Base abgeleitet ist, sollten Sie anstelle von statischen Casts einen dynamic_pointer_cast verwenden. Das System kann erkennen, wann / ob Ihre Besetzung nicht korrekt ist.

David Rodríguez - Dribeas
quelle
Das System kann dies jedoch nicht erkennen, wenn Base keine virtuellen Mitglieder hat. Dynamic_cast ist nur für Klassen mit virtuellen Mitgliedern magisch.
Aaron
Auch gibt es einen Performance-Hit. Wenn Sie wirklich wissen, dass die Umwandlung immer erfolgreich sein sollte, funktioniert static_cast ohne Laufzeitaufwand.
Joseph Garvin
... normalerweise kein Laufzeitaufwand . Ich kann mich nicht an die Details erinnern, aber bei virtueller Mehrfachvererbung oder einem anderen Eckfall gibt es technisch gesehen Overhead, aber immer noch weniger als dynamic_cast.
Joseph Garvin
Es ist möglich, dass dynamic_cast nicht funktioniert, wenn sich die abgeleitete Klasse in einer anderen Bibliothek als der Basisklasse befindet.
Andrei Bica
2

Es ist erwähnenswert, dass es einen Unterschied in der Anzahl der von Boost bereitgestellten Casting-Operatoren und der Implementierung von TR1 gibt.

Der TR1 definiert nicht den dritten Operator const_pointer_cast ()

Mloskot
quelle
Gemäß dieser Literaturstelle , const_pointer_castist in C ++ 11 verfügbar.
Siu Ching Pong -Asuka Kenji-