auto_ptr vs. scoped_ptr
-
Hi
Hab mal ne Frage betrefend smart pointern. Ich will folgenden Code sicher machen und das ist wohl ein Fall für eben diese:
{ View* pView = factory.create("Hello World!"); pView->show(); delete pView; }Hab mir auch den Artikel durchgelesen und hier brauche ich ja keine Referenzzählung, da das Objekt gleich wieder zerstört werden wird. Zuweisungen sind ja auch nicht vorgesehen.
Welche der beiden, auto_ptr oder boost::scoped_ptr, sind denn hier "besser" im Sinne von Performance und Design?Und ein zweites Beispiel ist hier:
File* pFile = new TxtFile; pFile->load(sFilename);Wobei TxtFile von der abstrakten Klasse File erbt und ich nachher virtuelle Funktionen (zB load()) drauf aufrufen möchte. Geht das auch mit smart pointern, und wenn ja hätte ich die gleiche Frage wie oben.
Und generell ne Frage, kann man eigentlich komplett auf Zeiger verzichten in C++?
Danke schonmal im voraus
Grüsse
-
boost::scoped_ptr lässt sich gar nicht kopieren also geht es gar nicht damit!!
-
scoped_ptr bietet dir keine Kopiersemantik, während dir auto_ptr eine etwas merkwürdige Kopiersemantik (destruktives Kopieren) anbietet. Daher sollte man scoped_ptr vorziehen.
Und generell ne Frage, kann man eigentlich komplett auf Zeiger verzichten in C++?
Ja. Zumindest indirekt
-
Class Clever schrieb:
Welche der beiden, auto_ptr oder boost::scoped_ptr, sind denn hier "besser" im Sinne von Performance und Design?
Die sollten, wenn ich das richtig sehe hier exakt gleich sein. Ich würde trotzdem den scoped_ptr verwenden, der Name ist irgendwie expressiver.
Class Clever schrieb:
Und ein zweites Beispiel ist hier:
File* pFile = new TxtFile; pFile->load(sFilename);Wobei TxtFile von der abstrakten Klasse File erbt und ich nachher virtuelle Funktionen (zB load()) drauf aufrufen möchte. Geht das auch mit smart pointern, und wenn ja hätte ich die gleiche Frage wie oben.
Die Art des Smartpointers, die du wählst, hängt nicht von Methoden oder ähnlichem ab (alle verhalten sich bei Dereferenzierung grundsätzlich gleich), sondern von der gewünschten Lebensdauer des bezeigten Objekts.
Class Clever schrieb:
Und generell ne Frage, kann man eigentlich komplett auf Zeiger verzichten in C++?
Wenn du stattdessen Smartpointer oder Referenzen benutzt, eigentlich schon. Aber manchmal brauchst du dennoch einen Zeiger (zB. für Bibliotheken).
-
Danke für die schnelle Antworten.
Also wenn scoped_ptr nicht kopierbar ist, kann ich den nicht als Rückgabewert meiner Funktion create() verwenden oder wie? Soll die dann trotzdem einen normalen Zeiger zurückgeben?
Meine Factory Methode bis jetzt:View* Factory::create() const { return new View(); }Und beim zweite Beispiel müsst ich dann einfach pFile.get()->load() machen oder wie?
-
Class Clever schrieb:
Danke für die schnelle Antworten.
Also wenn scoped_ptr nicht kopierbar ist, kann ich den nicht als Rückgabewert meiner Funktion create() verwenden oder wie? Soll die dann trotzdem einen normalen Zeiger zurückgeben?Ich würde einen shared_ptr zurückgeben.
Class Clever schrieb:
Und beim zweite Beispiel müsst ich dann einfach pFile.get()->load() machen oder wie?
Nein. pFile->load() funktioniert auch, das ist der Trick an der Sache (operator* und operator-> überladen). Hast du dich eigentlich überhaupt mal mit Smartpointern beschäftigt?!
-
Nein. pFile->load() funktioniert auch, das ist der Trick an der Sache (operator* und operator-> überladen). Hast du dich eigentlich überhaupt mal mit Smartpointern beschäftigt?!
Nein, damit fang ich doch grade an.

Ich würde einen shared_ptr zurückgeben.
Im Artikel steht die seien etwas langsamer, daher dacht ich das ein scoped_ptr besser wär, aber ich wers mal versuchen.
Danke für die Hilfe.

-
Also ich habs jetzt doch so:
{ boost::scoped_ptr<View> pView( factory.create("Hello World!") ); pView->show(); }Denn eigentlich bin ich zu faul die Schnittstellen aller factories zu ändern.
-
.filmor schrieb:
Class Clever schrieb:
Danke für die schnelle Antworten.
Also wenn scoped_ptr nicht kopierbar ist, kann ich den nicht als Rückgabewert meiner Funktion create() verwenden oder wie? Soll die dann trotzdem einen normalen Zeiger zurückgeben?Ich würde einen shared_ptr zurückgeben.
Ne, da bietet sich ein auto_ptr an. shared_ptr sollte man vermeiden, wenn es geht
-
ihr könntet auch 'nen GC verwenden, damit wären wie durch ein wunder alle smart-pointer überflüssig

-
ten, zeig mir eine GC Implementierung für C bzw. C++ und ich zeig dir einen GC der stinkt.
Ernsthaft.
-
Class Clever schrieb:
Also ich habs jetzt doch so:
{ boost::scoped_ptr<View> pView( factory.create("Hello World!") ); pView->show(); }Denn eigentlich bin ich zu faul die Schnittstellen aller factories zu ändern.
Geht das echt?

-
hustbaer schrieb:
ten, zeig mir eine GC Implementierung für C bzw. C++ und ich zeig dir einen GC der stinkt.
Ernsthaft.gibts da nix vernünftiges?
das erschreckt mich jetzt aber.
man liest doch ständig in den ganzen flamewars, dass man einfach nur eine GC-library mit hinzulinken kann, und schon hat man garbage collection wie die grossen...btw: wieso gibts überhaupt etliche verschiedene typen von smart pointern?
kann nicht mal einer 'ne smartpointerklasse coden, die für alles geht?
-
ten schrieb:
btw: wieso gibts überhaupt etliche verschiedene typen von smart pointern?
Weil es etliche verschiedene Anforderungen gibt, die man an einen Smart-Pointer stellen kann.
kann nicht mal einer 'ne smartpointerklasse coden, die für alles geht?
Mal davon abgesehen, dass so eine Klasse jedem Grundprinzip der OOP bzw. der Programmierung im allgemeinen widersprechen würde, wird das schlicht nicht gehen. Du kannst ja auch nicht eine Container-Klasse schreiben, die alle denkbaren Container-Ausprägungen repräsentieren kann.Es es gibt natürlich Ansätze (z.B. Lokis Smart-Pointer), die Variabilität durch verschiedene Policies ermöglichen und diese dann in einer Template-Klasse aggregieren. Das ist dann aber natürlich auch nicht "eine Klasse für alles", da verschiedene Instanziierung verschiedene Klassen generieren...
ten, zeig mir eine GC Implementierung für C bzw. C++ und ich zeig dir einen GC der stinkt.
Ernsthaft.Das würde ich so nicht unterschreiben. Es gibt durchaus brauchbare GC-Implementierungen für C++. Auch das sind sicher keine "one size fits all"-Ansätze, aber für konkrete Einsatzgebiete sind sie dennoch brauchbar.
Bsp: http://www.hpl.hp.com/personal/Hans_Boehm/gc/
-
Ich nehme jetzt nicht das J-Wort in den Mund (Flameware-Gefahr!), aber selbst bekannte GC-Implementierungen lassen sich per VM-Startparameter für Client- und für Server-Betrieb ausrichten. D.h. auch hier: in etablierten GC-Sprachen, gibt es keinen allgemeingültigen GC. Sondern es muß vom User entschieden werden, welchen GC-Typ er nun für seine Aufgabe nutzen will.
-
{ boost::scoped_ptr<View> pView( factory.create("Hello World!") ); pView->show(); }Das ist scheints böse, weil nicht exceptions sicher

Scott Meyers Effective Trick 17 (Im Ernst
)Speichern Sie mit new erzeugte Objekte in intelligenten Zeigern in eigenständiger Anweisung.
-
Class Cleverer schrieb:
{ boost::scoped_ptr<View> pView( factory.create("Hello World!") ); pView->show(); }Das ist scheints böse, weil nicht exceptions sicher

Scott Meyers Effective Trick 17 (Im Ernst
)Speichern Sie mit new erzeugte Objekte in intelligenten Zeigern in eigenständiger Anweisung.
Warum sollte das nicht exceptionsicher sein?
Edit:
Achso, die create Funktion wurde ja immernoch nicht geändert und gibt weiterhin ein View* zurück..
-
Class Cleverer schrieb:
{ boost::scoped_ptr<View> pView( factory.create("Hello World!") ); pView->show(); }Das ist scheints böse, weil nicht exceptions sicher

Scott Meyers Effective Trick 17 (Im Ernst
)Speichern Sie mit new erzeugte Objekte in intelligenten Zeigern in eigenständiger Anweisung.
Im Ernst, es sind nur Richtlinien

In diesem Fall kann es keine Resourcenlecks geben ... Schau dir nochmal das Kapitel an, da gehts um die Reihenfolge der Auswertung von Argumenten, wodurch Resourcenlecks auftreten könnten.
Doch hier hast du einen "sauberen" Fall.
-
Wäre es denn ok von der fyctory nen View* Pointer zurückzugeben?
Ansonsten bau ich mir lieber grad nen Intrinsic_ptr ein..
-
Es wäre logisch und richtig, factory.create eine auto_ptr zurückgeben zu lassen. Aus mir unverständlichen Gründen kann ein scoped_ptr keine auto_ptr direkt konsumieren. Folglich würde das ganze dann so aussehen:
{ boost::scoped_ptr<View> pView( factory.create("Hello World!").release() ); pView->show(); }Es spricht aber wohl nichts dagegen, statt dessen einen auto_ptr für pView zu benutzen. Andererseits ist die Variante mit release auf ihre Weise auch sehr expressiv. Prinzipiell bin ich ja der Meinung, das jeder Smartpointer, der ownership repräsentiert, fehlerhaft designed ist, wenn er keine kompatiblen auto_ptr konsumieren kann.
Wenn allerdings klar ist, das factory.create einen auto_ptr zurückgibt - also der Ausdurck so oder so sicher ist, wird die ganze Sache viel einfacher (und eben so, wie es eigentlich sein soll *wink richtung GC-Vertreter*):
factory.create("Hello World!")->show();und gut.