unique_ptr und Lebenszeit
-
Nicht wirklich. Ist das was du willst?
class A { std::unique_ptr<int> p_; public: A() {...} int* get() { return p_.get(); } }; int main() { A a; { int* p = a.get(); } // Hier willst du benachrichtigt werden, da p aus dem Scope geht? }
-
Derzeit schicke ich einfach blanke Zeiger zurück und es funktioniert auch alles, keiner der Clients lebt länger als die "Server"-Objekte, so ist die Software aufgebaut.
Genau so soll es auch gemacht werden. Das ist die empfohlene Vorgehensweise. Kein Grund es anders zu machen.
-
Genau, da möchte ich beurteilen können, ob das Programm bei Dereferenzierung von p noch das tut, was es tun soll. Wenn man einen bösen Fehler einbaut, könnte ja an die gleiche Speicherposition ein anderes Objekt vom selben Typ erstellt worden sein, oder was gänzlich anderes, was dennoch erstmal nicht zu Access Violations und hinterher zu obskuren Fehlern führt. Außerdem soll es so erschwert werden, aus Versehen einen der blanken Zeiger zu delete'n.
-
Ich denke, er will eher sowas:
std::unique_ptr<T> p = ... //... some_checkable_ptr<T> c = p; //p koennte nun sterben if(c.lock()) //nur, wenn p noch gültig { c->foo(); }Ist aber ziemlich gefährlich. Außerdem würde der unique_ptr, damit das funktionieren kann, nicht mehr so schön simpel sein können.
-
Decimad schrieb:
Genau, da möchte ich beurteilen können, ob das Programm bei Dereferenzierung von p noch das tut, was es tun soll. Wenn man einen bösen Fehler einbaut, könnte ja an die gleiche Speicherposition ein anderes Objekt vom selben Typ erstellt worden sein, oder was gänzlich anderes, was dennoch erstmal nicht zu Access Violations und hinterher zu obskuren Fehlern führt.
Wenn die Lebenszeit der Objekte des Servers an die Lebenszeit des Servers gebunden sind, dann ist ein Nutzer selbst schuld, wenn er nachdem der Scope des Servers verlassen wurde noch irgendwelche Zeiger auf seine Objekte dereferenziert. Wenn das nicht der Fall ist, willst du keinen unique_ptr. (Da die Objekte dann ja offensichtlich nicht alleine dem Server gehören.)
-
Na klar ist das ein Fehler im Client-Code, ich achte auch darauf, dass sowas nicht vorkommt.
Aber wenn ich es mal verbocke, würde ich gerne mit einer Riesenkanone darauf hingewiesen werden, inklusive Hand aus dem Monitor, die mein Gesicht gegen die Mattscheibe presst. Außerdem würde das den Quelltext noch "erklärender" gestalten und "versteckte" Abstürze verhindern.
-
Dafuer gibt es: Debugger, Tests, formale Verifikation, ... Ich halte nichts davon, zusaetzlich Komplexitaet einzubauen. Das ist genauso, wenn ich in meinem Haus die Fenster vergittere, damit ich nicht aus Versehen hinausfalle.
-
Bei einem versteckten Absturz kommt aber auch der Debugger (und die Access Violation) zu spät. Es wäre ja auch nur ein Debugging-Tool (und eines zur Selbsterklärendem Code und Disziplinierung im Umgang mit diesen Zeigern) für mich, in Release-Builds könnte man die ganzen Zeiger ja auf unique_ptr und blanke Zeiger typedefen (der deref-Operator vom weak_ptr würde halt sofort eine Ausnahme generieren können im Debug-Build, wo ein richtiger Zeiger noch "gültigen" Speicher vorfände).
Vielleicht implementiere ich mir das einfach selber mal, so zum Spaß
-
Ich habe auch schon über so etwas nachgedacht. Zumindest für einen Debugmodus ist das interessant, so baumelnde Zeiger abfangen zu können.
Das erinnert mich an Qt's "guarded pointers". Die funktionieren aber nur, wenn man von einer bestimmten Klasse (QTObject) ableitet. Der QTObject Destruktor lässt dann irgendwie die entsprechenden QGuardedPtr-Instanzen auf 0 setzen.
-
Und naja, ohne mich bloßstellen zu wollen, ich hätte mir schon einige Male viel Zeit im Debugger, der zu spät angesprungen ist, gespart, nachdem ich einen total dämlichen Fehler im Quelltext gemacht habe. Also es ist nicht "könnte mich davor bewahren" sondern in Nachhinein hätte es mir schon wertvolle Zeit erspart.
Naja, vielleicht werde ich auch irgendwann der Debugger-Guru, der in automatisch generierten Destruktor-Calls die hinter der Message-Pumpe stattfinden noch den exakten Programmverlauf nachverfolgen können. Bis dahin würde mir das viel Ärger abnehmen, stelle ich mir vor.
-
Dann kann man auch seine Pointer auf -1 nach dem Loeschen setzten. Darueber hinaus macht Visual C++ im Debug-Modus schon genug.
-
Pointer sind üblicherweise unsigned.
-
Es gibt niemals genug, das habe ich wie gesagt schon am eigenen Leib erfahren müssen!
Abgesehen davon finde ich natürlich toll, was der Debugger schon von Haus aus für micht schafft, will mich hier ja nicht über den Debugger beklagen.
-
314159265358979 schrieb:
Pointer sind üblicherweise unsigned.
Pointer sind weder signed noch unsigned. Es ist Ansichtssache, ob sich der Stack unter oder weit über NULL befindet. Dessen ungeachtet kann man aber auch vorzeichenlose Variablen auf -1 setzen; bei vorzeichenlosen Integern wird das Modulo 2Breite verrechnet, also auf den maximal darstellbaren Wert des Datentyps umgemünzt. Das findet man auch recht häufig, beispielsweise im Standard in der Definition von std::basic_string:
static const size_type npos = -1;
-
knivil schrieb:
Das ist genauso, wenn ich in meinem Haus die Fenster vergittere, damit ich nicht aus Versehen hinausfalle.

-
Für mich wäre es so, als ob ich die Fenster an meinem Haus vergittere, weil ich schon zweimal herausgefallen bin und dann mit Knochenbrüchen mehrere Wochen ausfiel

-
Wenn man unique_ptr so nutzt, sollte die Serverinstanz so plaziert sein, dass es offensichtlich ist wenn irgendein Pointer aus dem Scope geht. Normalerweise sieht das doch so aus:
{ Server s; los_gehts(s); }Oder wie auch immer. Jedenfalls eindeutig so, dass man nicht mal eben Zeiger aus dem Scope mitnimmt.
-
Die Server-Objekte sind selber dynamisch erzeugt. Die Lebenszeiten und -Räume erstrecken sich über unzählige Dateien und über Event-betriebene Prozessgrenzen. Es ist halt eine dynmische und flexible GUI-Anwendung, mit eingebautem Undo, Modellen, Views etc. Da kann man halt auch mal einen Bock einbauen, finde ich.
Dieses super-übersichtliche C++, das man hier in den Minimalbeispielen sieht, habe ich immer nur bei meinen schönen Konsolenapplikationen oder bei Schleifenbasierten 3D-Sachen.
-
Model-View-Controller ...
PS: Ja, das Problem ist abgehackt.
-
Decimad schrieb:
Dieses super-übersichtliche C++, das man hier in den Minimalbeispielen sieht, habe ich immer nur bei meinen schönen Konsolenapplikationen oder bei Schleifenbasierten 3D-Sachen.
Dann bau deine GUI-Anwendung halt so, dass sie wieder wie dieses super übersichtliche C++ aussieht. Das ist nicht unmöglich. z.B. könntest du die Lebenszeit eines Servers einfach an das Fenster koppeln, über das er gesteuert wird.