Ist das hier falsche Benutzung eines shared_ptr?
-
EOutOfResources, im folgenden ein kurzes Beispiel (hier sogar nur mit lokaler Variablengültigkeit).
Deine Aufgabe besteht darin, ohne Smart-Pointer äquivalenten Code zu schreiben. Gehe davon aus, dass jede aufgerufene Funktion der Klassen
Base,Derived1undDerived2eine Exception werfen kann.int Fn() { scoped_ptr<Derived1> a(new Derived1); scoped_ptr<Base> b; if (...) b.reset(new Derived1); else b.reset(new Derived2); if (b->MemFn1()) return 2; a->MemFn2(); if (b->MemFn3()) return 4; else return 7; }
-
Im Grunde weiß EOutOfResources ja selber, dass seine Haltung Quatsch ist und ein Indiz für Unerfahrenheit ist. Nur aufgrund falschen Stolzes kann er halt jetzt nicht seinen Fehler eingestehen...
-
das ist möglich, ich hab sogar in etwa was vor meinem geistigen auge, aber da kommt redundanter code dazu, und jede einzelne exception wird einzeln per try abgefangen...
-
Nexus schrieb:
EOutOfResources, im folgenden ein kurzes Beispiel (hier sogar nur mit lokaler Variablengültigkeit).
Deine Aufgabe besteht darin, ohne Smart-Pointer äquivalenten Code zu schreiben. Gehe davon aus, dass jede aufgerufene Funktion der Klassen
Base,Derived1undDerived2eine Exception werfen kann.int Fn() { scoped_ptr<Derived1> a(new Derived1); scoped_ptr<Base> b; if (...) b.reset(new Derived1); else b.reset(new Derived2); if (b->MemFn1()) return 2; a->MemFn2(); if (b->MemFn3()) return 4; else return 7; }int Fn() { Derived1 a; if (...) { Derived1 b; return helper(a,b); } else { Derived2 b; return helper(a,b); } } int helper(Derived1& a, Base& b) { if (b.MemFn1()) return 2; a.MemFn2(); if (b.MemFn3()) return 4; else return 7; }
-
Isomorph+ schrieb:
Im Grunde weiß EOutOfResources ja selber, dass seine Haltung Quatsch ist und ein Indiz für Unerfahrenheit ist. Nur aufgrund falschen Stolzes kann er halt jetzt nicht seinen Fehler eingestehen...
Jup, das kommt davon wenn man schreibt ohne nachzudenken.

-
Nicht schlecht, life! Was machst du, wenn wir
if (...) b.reset(new Derived1); else b.reset(new Derived2);ersetzen durch
Base* CreateDerived(); // Funktionsdeklaration b.reset(CreateDerived());? Oder falls wir das
Derived-Objekt nach der Funktion noch verwenden wollen?
-
Oder falls wir leserlichen Code wollen?

-
Nexus schrieb:
Nicht schlecht, life! Was machst du, wenn wir
if (...) b.reset(new Derived1); else b.reset(new Derived2);ersetzen durch
Base* CreateDerived(); // Funktionsdeklaration b.reset(CreateDerived());? Oder falls wir das
Derived-Objekt nach der Funktion noch verwenden wollen?
Ich verwende Smartpointer. Wobei ich bei deinem Beispiel die Lösung ohne Smartpointer sogar fast eleganter finde..
-
Smartpointer helfen halt, dass die Speicherverwaltung automatisch erledigt wird. Aber ich finde, die sind kein Muss. Die inflationäre Benutzung davon ist in meinen Augen nicht immer nötig. Es gibt aber viele Fälle, in denen die hilfreich sind.
-
Eisflamme schrieb:
Aber ich finde, die sind kein Muss. Die inflationäre Benutzung davon ist in meinen Augen nicht immer nötig.
Sehr vorsichtig ausgedrückt

Normalerweise besteht aber kein Grund, Smart-Pointer nicht zu verwenden. Gerade bei so einer einfachen Sache wie
scoped_ptr, wo man sich dasdeletesparen und sich sicher sein kann, dass der Code auch nach einer Änderung in einem Jahr noch ohne Leaks ist. Was eher ein Problem darstellt, ist der übermässige Einsatz vonshared_ptr, obwohl man keinen geteilten Besitz will. Zum Beispiel in STL-Containern. Meist will man stattvector<shared_ptr<T>>einenptr_vector<T>.
-
Mache ich davon Gebrauch, dass man die Verwaltung einer Ressource einem anderen Objekt überlässt? Ja. Gerne.
Nutze ich schlaue Zeiger? So gut wie gar nicht. Hat jetzt aber nichts mit Prinzipien zu tun. Ich habe schlaue Zeiger bisher so gut wie gar nicht benötigt. Das hat sicherlich auch was mit meinen Anwendungsbereichen zu tun (Ich bastel zB kaum GUIs).
-
@krümelkacker:
Ich finde es mit Smart-Pointern halt viel übersichtlicher, weniger fummelig und weniger fehleranfällig wenn man Ownership transferiert.
Spätestens mit C++0x gibt es IMO kein gutes Argument mehr es nicht zu machen. Denn da haben wirstd::unique_ptr, und der ist schlank und movable. Und alles wird gut