Ich habe ein paar Projekte, die boost::shared_ptr
oder std::shared_ptr
ausgiebig verwenden (Ich kann zu jeder Implementierung bald genug konvertieren, wenn es eine gute Antwort auf diese Frage gibt für den einen, aber nicht den anderen). Die Boost-Implementierung verwendet Boost.Assert, um die Rückkehr zu vermeiden, wenn während der Laufzeit ein leerer Zeiger (NULL) in operator*
oder operator->
angetroffen wird; während die libC++ -Implementation scheint keine Überprüfung zu haben.Anpassen von std :: shared_ptr oder boost :: shared_ptr um eine Ausnahme auf NULL Dereferenz zu werfen
Während natürlich die Gültigkeit einer shared_ptr
sollte vor der Verwendung überprüft werden, führt eine große, gemischt-Paradigma Codebasis mich zu einer Ausnahme-werfen Variante versuchen wollen; Der größte Teil des Codes ist relativ ausnahmebedingt und wird allenfalls auf einen hohen, aber fortsetzbaren Zustand stoßen, anstatt auf std::terminate()
oder segfault.
Wie sollte ich diese Accessoren am besten anpassen und gleichzeitig die Robustheit von shared_ptr
beibehalten? Es scheint, dass die Kapsel in einer throwing_shared_ptr
die beste Option ist, aber ich bin vorsichtig, die Magie zu brechen. Bin ich am besten dran, die Boost-Quelle zu kopieren und einfach die ASSERT
s in eine entsprechende throw
-Anweisung zu ändern?
Der tatsächliche Typ Name überall für den entsprechenden smart_ptr<T>
Typ verwendet wird, ist ein typedef aus einem Makro erweitert; das heißt ForwardDeclarePtr(Class)
erweitert um so etwas wie:
class Class;
typedef boost::smart_ptr<Class> ClassPtr;
Alles vergeht, nimmt, oder speichert eine ClassPtr
- so kann ich den zugrunde liegenden Typ ziemlich frei ersetzen; und ich vermute, dass dies das potenzielle Problem des Slicing/Hiding mildert.
Diese Antwort zu akzeptieren, weil es ein bisschen einfacher ist, das Design, die Sicherheit und die Verwendung der Kapselung in Kommentaren zu erklären (Klassen haben die 'shared_ptr'-Mitglieder die ganze Zeit). @ KevinBallard ist auch richtig, though. – rvalue