Korrekte Modellierung + Implementation
-
Haha was für ein Haufen heißer Dampf hier von sich gegeben wird ist zum brüllen. Für jeden Außenstehenden sind die Leute die hier "geholfen" haben offensichtlich die mit den Egoproblemen, anders kann ich mir die Autistenreaktionen hier nicht erklären.
Aber noch besser, jetzt werden mir auch noch Internetforen erklärt, der Thread ist gold. Bisher hat quasi keiner hier irgendein wertvollen, relevanten Tipp gegeben Herr Dachschaden (Name ist Programm, find ich gut).
Und ob das bekackte Fenster jetzt den Desktop anfassen darf, spielt noch immer keine Rolle. Ich habs Gefühl hier will jeder nur mal seinen Schwanz auspacken, und weil nix Relevantens einfällt schlägt man halt auf Randbedingungen ein, die völlig belanglos für die gestellte Frage sind.
Und was jetzt in einem Fachforum um Rat bitten mit Fußgängerbelästigung zu tun hat, ist mir auch ein Rätsel, ich fürchte ich bin noch nicht lange genug sozial isoliert wie der Rest hier.
Ich hab mal in einem Kinderzeichentrick gelernt: "Wenn man nichts Gutes zu sagen hat, sollte man lieber einfach still sein", das trifft auf mich zu, und auf quasi alle die hier "geholfen" haben.
Ich find euch unterhaltsam, leider auch nicht mehr.
-
Naja, was soll man da noch sagen... selbst einfachste Dinge nicht verstanden. Viel Erfolg bei deinem Projekt.
-
Endlich nach langen Jahren der Traurigkeit mal ein Troll hier im Forum.

-
Ach, ich seh das positiv. Pfuscher wie der TE sichern mir den Lebensabend.

-
Hähä ne, ich bin Hobbyfrickler, wenn ich Murks zusammenschuster stört nur mich das und bringt dir kein Geld.
Ich hatte ja gehofft, dass die Götter hier im Forum sich erbarmen würden, mich etwas in die richtige Richtung zu leiten, aber die Wege der Herren sind unergründlich und ich bin leider nicht würdig.
Ich bin froh, dass es solche Bastionen der Überheblichkeit noch gibt. Anderswo sind die meisten Communities weiter und sind sogar wirklich hilfbereit, das nervt auf Dauer, wenn man auf Erfahrung von anderer bauen kann.
In einem Punkt muss ich aber doch Kritik üben - Linuxcommunities im IRC sind noch eine Ecke asozialer als ihr, da ist also definitiv noch Luft nach oben!
-
@therapy
Das Problem ist dass du das was du da "modellieren" möchtest nicht klar definiert hast. Nicht nur hier im Forum nicht klar beschrieben, sondern auch dass du selbst keinen echten Plan hast was du eigentlich modellieren willst.Da stellen sich Fragen wie
- Wem gehören die Fenster? (Wer hat "ownership" - also wer bestimmt wann ein Fenster zerstört wird?)
- Ist es möglich/erlaubt dass es nicht-besitzende Referenzen auf Fenster gibt, die erhalten bleiben können/dürfen nachdem ein Fenster zerstört wurde?
- Wenn ja, wie soll das System reagieren wenn versucht wird so eine "verwaiste" Referenz zu verwenden?
usw.Das sind Dinge die erstmal mit C++ nichts zu tun haben. (Die aber geklärt sein sollten bevor man versucht zu entscheiden wie man das jetzt vernünftig in C++ umsetzen kann.) Und die man auch nicht in 2-3 Sätzen erklären kann. Das hat manni66 vermutlich mit seinem Beitrag gemeint.
Das will dir aber in den Kopf nicht rein. Du bist einfach zu sehr davon überzeugt zu wissen worum es geht, zu wissen dass das eigentliche Problem nur deine beschränkten C++ Kenntnisse sind, und nicht etwa grundlegendere Überlegungen usw.
Wenn du weiterhin der Meinung sein willst der Grund für das offensichtliche Kommunikationsproblem hier wäre auf "unserer" Seite und nicht auf deiner, bitte gern. Mach dir ruhig selbst vor was auch immer du dir vormachen willst.
-
Ja wenn meine Beschreibung nicht reicht, dann fragt halt nach meine Güte. Woher soll ich denn wissen, ob ihr mir folgen könnt ohne dass auch nur eine Person sagt "Deine Beschreibung ist uneindeutig - was willst du".
Ich probiers ein letztes Mal, wobei ich nicht davon ausgehe, dass es noch irgendwen interessiert.
Ich habe eine Client-Klasse. Die verwaltet Fenster. Von extern (X-Server, aber das soll keine Rolle spielen für Leute die keine X-Programmierung machen) kriege ich die Nachricht "Es ist ein neues Fenster aufgetaucht".
Ich will also dieses Fenster, und alle Attribute (sind einige) verwalten. Nun möchte ich was eben der Zweck eines Window Managers ist, Fenster auf Desktops einteilen. Aber da auch das hier wohl zu kompliziert ist und mir Unfähigkeit vorgeworfen wird, sagen wir es anders:
Client hat eine dynamische Ressource zu verwalten, die im Ctor aquiriert wird, und im Dtor freigegeben werden soll (in meinem Fall: Registrierung bei Desktop-Klassen, aber das hat niemand zu interessieren, es ist einfach so, dass dynamische Daten da sind, fertig aus).
Nun, dynamische Ressource heißt ja, dass ich sehr vorsichtig bei Kopien sein muss, und da ich Fenster/Clients (ist das gleiche, das eine ist X-Lib-Terminologie) in einem beliebigen (um Gottes Willen bitte nicht wieder eine Diskussion über Container) STL-Container verwalten möchte, wird das komplizierter.
Einfachstes Beispiel: Ich packe Client* in einen Container und Problem gelöst. Lösche ich ein Client, gibt der Speicher frei und gut ist. Ich will aber keine Rawptr.
Mein Ziel und meine Lösung momentan:
std::container<client> clients
Das erreiche ich indem ich copy ctor (es ergibt genau NULL Sinn Clients zu kopieren, es gibt nur ein physisches Fenster, und dazugehörige dynamische Daten duplizieren ergibt auch null Sinn) und Assignment verbiete. Dann hab ich den Move-Ctor definiert und nun geht sowas wie:
clients.push_back(std::move(client(...));
Damit wird der Client-Ctor exakt einmal aufgerufen, ich kann Daten aquirieren und im Dtor freigeben. Die Lösung fine ich fast okay, denn ich habe simpel verständlich eine authoritative Liste aller Fenster, die sich autonom um die dynamische Daten kümmern, wenn ich sie aus dem Container werfe und gut ist. Bis auf dass ich einige Mechaniken rundrum nicht verstehe.
Diese Lösung habe ich mir zusammen geschustert und ich hatte eigentlich gehofft mir schlägt jemand sowas vor oder sagt, warum das keine gute Idee ist, wieso Smart-Pointer im Container vielleicht doch besser sind und und und.
Es kamen aber keine gezielten Fragen sondern nur Bullshit.
-
sdfsdfggg schrieb:
Client hat eine dynamische Ressource zu verwalten, die im Ctor aquiriert wird, und im Dtor freigegeben werden soll
Also RAII/RRID. OK.
sdfsdfggg schrieb:
Nun, dynamische Ressource heißt ja, dass ich sehr vorsichtig bei Kopien sein muss, und da ich Fenster/Clients (ist das gleiche, das eine ist X-Lib-Terminologie) in einem beliebigen STL-Container verwalten möchte, wird das komplizierter.
Jain. Man kann RAII Objekte wunderbar kopieren und in Collections tun. Beispielsweise
std::string. Man muss nur damit klarkommen dass beim Kopieren u.U. ne Exception fliegen kann.In deinem Beispiel ist allerdings primär erstmal 'was anderes relevant. Nämlich dass es überhaupt keinen Sinn macht so etwas wie eine "ConnectedClient" Klasse zu kopieren. Weil die konzeptuell nicht kopierbar ist. Weil ja nicht magisch eine neue Connection mit einem neuen Client dran entsteht wenn du das "ConnectedClient" Objekt kopierst. Zu der Frage ob es wegen dynamische Ressource schwierig wird oder nicht kommt man also gar nicht mehr.
Form follows function, nicht umgekehrt.sdfsdfggg schrieb:
Einfachstes Beispiel: Ich packe Client* in einen Container und Problem gelöst. Lösche ich ein Client, gibt der Speicher frei und gut ist. Ich will aber keine Rawptr.
Ja, gute Entscheidung. Besitzende Raw-Pointer sind böse (fehleranfällig). Und collections aus besitzenden Raw-Pointern sind nöch mehr böse.
sdfsdfggg schrieb:
Mein Ziel und meine Lösung momentan:
std::container<client> clients
Das erreiche ich indem ich copy ctor (es ergibt genau NULL Sinn Clients zu kopieren, es gibt nur ein physisches Fenster, und dazugehörige dynamische Daten duplizieren ergibt auch null Sinn) und Assignment verbiete. Dann hab ich den Move-Ctor definiert und nun geht sowas wie:
clients.push_back(std::move(client(...));
Damit wird der Client-Ctor exakt einmal aufgerufen, ich kann Daten aquirieren und im Dtor freigeben. Die Lösung fine ich fast okay, denn ich habe simpel verständlich eine authoritative Liste aller Fenster, die sich autonom um die dynamische Daten kümmern, wenn ich sie aus dem Container werfe und gut ist. Bis auf dass ich einige Mechaniken rundrum nicht verstehe.
Diese Lösung habe ich mir zusammen geschustert und ich hatte eigentlich gehofft mir schlägt jemand sowas vor oder sagt, warum das keine gute Idee ist, wieso Smart-Pointer im Container vielleicht doch besser sind und und und.
Also...
Movable... hm. Ja, kann man machen. Muss man in dem Fall aber nicht. Weil es auch nicht ganz ungefährlich ist.Wenn du als
std::containerz.B.std::vectorwählst, dann musst du damlit leben dassstd::vectorhin und wieder mal ne Reallocation machen wird. Dabei werden dann alle Objekte verschoben. Dabei verändern sich ihre Adressen. Bzw. auch einfach wenn du in der Mitte ein Objekt rauslöscht.Das heisst dann dass du z.B. nicht in einem Thread ein Client Objekt verwenden darfst, während du in einem anderen ein neues einfügst oder ein bestehendes löscht. Das kann egal sein (wenn alles single threaded ist, und es keine Callbacks gibt die zum "unpassenden" Zeitpunkt aufgerufen werden könnten). Es kann aber auch wichtig sein.
Generell mache ich Objekte ersmtal noncopyable UND nonmovable wenn sie konzeptuell nicht kopierbar sind. Weil es Kopfschmerzen spart. Wie bei jeder Faustregel wird es Ausnahmen geben wo es sinnvoll ist 'was anderes zu machen, aber bisher sind mir da keine begegnet.
D.h. ich würde einfach mal sowas wie
vector<unique_ptr<Client>>machen. Bzw. u.U. auchmap<SomeKeyType, unique_ptr<Client>>, wenn du z.B. sowieso die Möglichkeit brauchst nen Client anhand irgend einer ID rauszusuchen.Bei
map<>könnte man jetzt natürlich sagen: OK, beimapmüssen die Objekte sowieso nicht kopiert werden, und auch nicht verschoben, da kann man ja mitemplacearbeiten, und damit brauchen wir denunique_ptrnicht mehr. Könnte man sagen. Würde ich aber auch nicht machen. Und zwar weil du damit die komplette Konstruktionsphase des Client in denemplaceAufruf hineinverlagerst. Mit Multithreading wäre das wieder doof, weil du dann über den gesamten Zeitraum den der Client Ctor benötigt diemapgelockt halten müsstest.Bei
map<SomeKeyType, unique_ptr<Client>>hingegen lässt sich das leicht vermeiden: du konstruierst erstmal ganz gemütlich den neuen Client und verschiebst dann einfach denunique_ptrin die Map rein. (Hier ist es dann auch kein Problem wenn verschoben wird, da ja nur derunique_ptrverschoben wird - die Adresse des Client Objekts ändert sich ja deswegen nicht.)sdfsdfggg schrieb:
Es kamen aber keine gezielten Fragen sondern nur Bullshit.
Naja... die Frage die du in diesem Beitrag jetzt gestellt hast, hast du bisher einfach nicht gestellt. Dein erster Beitrag hier hat den Fokus recht deutlich auf die Sache mit den Desktops gelegt, das Thema wer sollte wen kennen usw. Davon ist hier jetzt auf einmal nicht mehr die Rede. Statt dessen stellst du eine ziemlich konkrete Frage, die ich dadurch auch (hoffentlich) ziemlich konkret beantworten konnte.
ps:
Bis auf dass ich einige Mechaniken rundrum nicht verstehe.
Da du nicht näher darauf eingehst, gehe ich mal davon aus dass dich das nicht weiter stresst dass du "einige Mechaniken rundrum" nicht verstehst. Falls doch, dann frag gerne nach. Wenn du konkret schreibst welche Mechaniken du nicht verstehst, dann wird sich sicher jemand finden der es dir erklärt.
-
solange klar ist, dass der container diese resource verwaltet, ist diese lösung standard. sobald das nicht mehr der fall ist, verwende unique_ptr und rohe zeiger, evtl. mit einem marker in der art "non_owning<T>".
lächerlich ist allerdings, dass du ursprünglich gefragt hast:
"Wie modelliere ich sowas konkret und ordentlich?" - ganz allgemein, und darauf auch antworten bekommen hast. weißt du, wenn sich hier ab und zu mal leute mit schwierigeren fragen und komplexen constraints (X-lib) herumplagen, dann ist das eher die ausnahme - ohne kontext gehe ich mal davon aus, dass mein gegenüber (fast) gar keine ahnung hat. wie du dich darüber so sehr aufregen kannst, ist mir völlig unverständlich.
-
Erstmal danke Hustbaer, das sind mal konkrete Antworten mit denen ich arbeiten kann.
Die Sache mit den Desktops steht noch genau wie im OP, nur dass ich das jetzt als "externe dynamische Ressource" deklariert habe und damit nun anscheinend eine Denkblockade gelöst wurde. Das find ich gut, konnte ich aber nicht ersehen, dass das das Problem anscheinend zu abstrakt macht. Aber das wäre damit nun geklärt.
Dass der Vector rumkopiert habe ich gar nicht bedacht. Meines Wissens nach ist das kein Problem, weil nur single-threaded (soweit ich weiß, aber falls ich einen Vector nehme schlage ich das nochmal nach, ob der X-Server Callbacks asynchron raushauen kann).
Die Idee mit map<id,uptr> find ich auch ganz dufte, aber ich glaube ich brauch das Window-Handle (=ID) im Client selbst, da ich die Klasse autonom halten möchte (d.h. sie kommuniziert selbst mit dem X-Server wenn nötig).
Die Diskussion unique_ptr (oder evt. generell std::container<smart_ptr>) war eigentlich meine Absicht im OP. Ich finde konzeptuel die Move-Lösung schön, dass konkrete Instanzen, und keine Pointer in einem Container sind. Ursprünglich hatte ich eine Lösung mit shared_ptr im Container, aber ich fand die einfach unschön, weil es faktisch keinen anderen Besitzer für die Ressource gibt/geben wird, wieso dann ein Konstrukt, das genau für sowas gemacht ist.
Vielleicht war mein "modernes C++" auch zu kryptisch und ich hätte direkt Move und Co. in den Raum werfen sollen.
Ich würde gerne weiter Fragen zur Move-Lösung stellen, denn auch wenn sie eventuell doch nicht so schön (oder einfach zu komplex für das einfache Szenario) ist, würde ich gerne einmal verstehen, wie man das schön aufzieht.
Ich weiß gerade nicht, ob es besser ist, einfach etwas Code zu posten, der nicht funktioniert (müsste ich erst eindampfen), oder eher erklären was ich vor hatte und wieso. Ich probiere mal letzteres.
Ich möchte den Copy-Ctor und Assignment-Operator private haben, denn es gibt keine sinnvolle Erklärung dafür, Client-Instanzen (die 1:1 "physische" Objekte verwalten) zu kopieren. Ich habe einen Ctor und einen Dtor, beide sind für die dynamische Ressource (= Registrierung bei Desktop-Instanzen u.a.) zuständig.
Ich habe einen Move-Ctor, damit ich Instanzen in einen noch nicht festgelegten Container werfen kann. Ich habe eine Status-Membervariable die lediglich dazu da ist, dem Dtor zu sagen "Du bist authoritativ, d.h. du darfst die externe Ressource quasi freigeben oder nicht". Im Move-Ctor scheine ich aber nun von Hand quasi sämtliche Attribute (das sind einige) vom Client&& zu kopieren, was ich sehr unschön finde.
Was ich eigentlich bräuchte wäre eine 1:1-Kopie vom gegebenen Client&&, welchem ich danach sage "Du bist NICHT mehr zuständig für externe Ressourcen". Das klingt nach Copy-Ctor + Variablenzuweisung. Aber der Copy-Ctor ist bisher "= delete" also nicht vorhanden. Ich bräuchte eigentlich den Default-Ctor, will den aber nicht public weil eine Kopie wie gesagt allgemein kein Sinn ergibt. Ich habe zufällig vorhin gesehen, dass C++11 aber ein explizites ctor = default erlaubt. Meinem Verständnis nach ist das exakt was ich will. Ein stumpfes elementweises Kopieren (=default copy ctor), dass ich aber explizit als private deklarieren kann (= default), so dass ich es intern verwenden kann. Da habe ich aber einige Compilerprobleme gekriegt, egal wie ich das versucht habe aufzuziehen.
Ist das soweit alles richtig gedacht, oder völlig daneben und man geht an die Sache anders heran um dieses "Private Kopie für einfache Implementierung des Move-Ctors erlauben"-Problem zu lösen?
-
gggggggs schrieb:
Die Idee mit map<id,uptr> find ich auch ganz dufte, aber ich glaube ich brauch das Window-Handle (=ID) im Client selbst, da ich die Klasse autonom halten möchte (d.h. sie kommuniziert selbst mit dem X-Server wenn nötig).
Es spricht mMn. nichts dagegen die ID doppelt zu haben, 1x als Key und 1x im Client. Betrachte es einfach als externen Index. Jetzt könnte man natürlich sagen: da sollte man gleich
setnehmen. Das Problem beisetist bloss dass man nur mehrconstZugriff auf die Objekte bekommt sobald sie in einemsetstecken. Weil diesetImplementierung halt das ganze Objekt als "Key" betrachtet, und sich der Key eben nicht ändern darf wenn das Objekt imsetsteckt. Natürlich gibt es Implementierungen wie Boost.Multiindex wo das kein Problem ist. Und es ist möglich dass da bei C++11/14/17 was geändert wurde, so genau kenne ich die neuen Standards nicht.Fakt ist aber dass es kein Problem ist eine immutable ID in einer
mapals Key zu verwenden, auch wenn diese ID nochmal im Objekt selbst gespeichert ist. So lange garantiert ist dass die ID gültig bleibt so lange das Objekt existiert, ist alles in Butter.gggggggs schrieb:
Die Diskussion unique_ptr (oder evt. generell std::container<smart_ptr>) war eigentlich meine Absicht im OP. Ich finde konzeptuel die Move-Lösung schön, dass konkrete Instanzen, und keine Pointer in einem Container sind.
Und ich finde die konzeptuell unschön

Die konkreten Gründe dafür hab' ich dir ja schon genannt. Weiters kommt es mir einfach komisch vor wenn Objekte die ganz klar eine "Identität" haben und etwas "physischem" entsprechen direkt rein in einem Container leben. Klar, das ist Bauchgefühl und für sich genommen kein guter Grund, aber naja. Ist halt so
gggggggs schrieb:
Ich möchte den Copy-Ctor und Assignment-Operator private haben, denn es gibt keine sinnvolle Erklärung dafür, Client-Instanzen (die 1:1 "physische" Objekte verwalten) zu kopieren.
Mach gleich
= deleteoder leite vonboost::noncopyableoder sowas ab. Ansonsten ja, klar, copyable oder assignable wäre hier ziemlich bekloppt.gggggggs schrieb:
Ich habe eine Status-Membervariable die lediglich dazu da ist, dem Dtor zu sagen "Du bist authoritativ, d.h. du darfst die externe Ressource quasi freigeben oder nicht".
Riecht nach einem Design-Bug. Wozu brauchst du das? Also ja, für "move-enabled" Typen braucht man das öfter mal. Was ein weitere Grund ist warum ich Typen nicht move-enable wenn es keinen guten Grund dafür gibt. Und nur "schöner" ist für mich kein guter Grund, wenn dann muss es z.B. praktischer oder klarer (einfacher zu verstehen) sein oder für gute Performance wichtig. Abgesehen von "wegen move" solltest du aber nie solche Flags haben. Alles was mir (ausser move) bisher untergekommen ist kann man lösen indem man Dinge feiner in Klassen aufteilt. Dazu gleich mehr.
gggggggs schrieb:
Im Move-Ctor scheine ich aber nun von Hand quasi sämtliche Attribute (das sind einige) vom Client&& zu kopieren, was ich sehr unschön finde.
Wenn alle Member move-enabled sind, dann kann dir der Compiler den Move-Ctor erstellen. Das Problem wird nun vermutlich dein Flag sein. Das kannst du aber wieder dadurch lösen indem du die Dinge feiner unterteilst. Wenn jedes Member selbst weiss ob es ein Move-Zombie ist oder "echt", dann kann sich jedes Member selbst freigeben. Wenn du jetzt ne Klasse mit haufenweise Attributen hast die du im Dtor nicht anfassen musst, und einem Member wo du ein "
if (!m_zombie) FreeSomething(m_something);" machst, dann fehlt dir einfach eine Klasse: die KlasseSomething.
Dann musst du nur fürSomethingeinen Move-Ctor schreiben. Der hat dann ja kaum 'was zu moven (typischerweise bloss ein Handle/eine ID/...), und ist daher denkbar einfach zu schreiben. Die Client Klasse braucht dann keinen eigenen Move-Ctor mehr, weilSomethingja bereits korrekt move-enabled ist, und damit der Move-Ctor den der Compiler automatisch generiert auch automatisch passt.gggggggs schrieb:
Ich habe zufällig vorhin gesehen, dass C++11 aber ein explizites ctor = default erlaubt. Meinem Verständnis nach ist das exakt was ich will. Ein stumpfes elementweises Kopieren (=default copy ctor), dass ich aber explizit als private deklarieren kann (= default), so dass ich es intern verwenden kann. Da habe ich aber einige Compilerprobleme gekriegt, egal wie ich das versucht habe aufzuziehen.
Ist das soweit alles richtig gedacht, oder völlig daneben und man geht an die Sache anders heran um dieses "Private Kopie für einfache Implementierung des Move-Ctors erlauben"-Problem zu lösen?
Ich glaube ich verstehe was du meinst. Du willst nen privaten, automatisch generierten Copy-Ctor, und den Move-Ctor dann als "inheriting ctor" implementieren, der erstmal diesen Copy-Ctor aufruft, und dann
other.m_zombie = true;macht.Halte ich für eine ganz schlechte Idee. Mach es so wie oben beschrieben (feiner kapseln).
BTW: Die oben Beschriebene Lösung ist auch nicht "neu", die gab es auch schon vor "move". Die Lösung ist die selbe für das Problem mit Klassen wo man mehrere dynamische Resourcen im Ctor anfordern möchte. Ohne Weiteres bekommt man damit dann nämlich ein Problem mit Exception-Safety. Nämlich wenn eine Exception beim Initialisieren der 2. Resource fliegt. Dann muss die 1. ja freigegeben werden. Dtor wird aber nicht aufgerufen, weil der Ctor ja noch nicht fertig gelaufen war. Also kapselt man feiner, so dass jede Klasse immer genau max. eine dynamische Resource im Ctor anlegt. Bzw. allgemeiner: Genau einen "do" Schritt im Ctor macht für den ein "undo" Schritt im Dtor nötig ist.
Und das ganze ist auch nicht nur ein "Trick" um die beschriebenen Probleme zu lösen, es ist viel mehr als das: sauberes Klassendesign, single Responsibility, wie auch immer man es nennen möchte. Wenn du anfängst generell so zu programmieren, wirst du merken dass dein Code automatisch einfacher und übersichtlicher wird. Weil du nicht mehr Dinge vermischt die eigentlich nicht vermischt werden sollten

-
Ich habe mich nach etwas hin und her doch für deine map<handle,unique_ptr>-Lösung entschieden. Ich finde das ist elegant (Client-Lookups handhabt nun z.B. ganz sauber die Map, kein Iterator-Gewurschtel), Das Problem mit meinen Verknüpfungen (bzw. eben die dynamischen Ressourcen die Client innehat) wird über den Unique-Pointer völlig transparent gelöst, ich kann also ohne Nachdenken Ctor/Dtor dafür verwenden, und sinnlose Operationen wie Clients kopieren o.ä. gehen von Natur aus durch den Unique-Ptr ebenfalls nicht.
Soweit finde ich das eine sehr saubere Lösung.
Eine Frage bleibt nun aber doch noch: Desktops sollen ebenfalls eine Referenz auf Fenster haben, die dort drauf sind. Was wähle ich hierfür? Theoretisch wäre ich mit Rawptr einverstanden, immerhin sagt der Client ja Bescheid, wenn er verschwindet, ich werde also niemals Nullzeiger haben. Außerdem ergibt es keinen Sinn, dass die Referenz auf einen Client im Desktop eine Art von Besitz ausdrückt. Wenn der X-Server sagt ein Client ist weg, ist weg. Das würde also zu Rawpointern passen.
Alternativ könnten Desktop-Instanzen nur eine Liste mit Handles verwalten, bräuchte dann aber Zugriff auf die gesamte Clientliste um mit denen auch tatsächlich zu interagieren.
Was davon ist sinnvoller - oder gibt es eine andere Variante? Auf Anhieb habe ich std::reference_wrapper und boost::ptr_vector gefunden, die wohl noch eine Alternative wären.
-
Roher Zeiger ist gut.
-
Oki, dann mach ich das so.
Ich möchte mich aufrichtig für die Hilfe bedanken, so eine Diskussion wie sie jetzt doch noch zustande kam, war, was ich eigentlich ursprünglich erhofft hatte.
Das Design bzw. die Implementation so gefällt mir sehr gut, weil simpel und elegant. Nun kann ich den Rest mit einer soliden Basis implementieren!
Vielen Dank!