Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

13.09.2015, 18:49

RAII über method-scope

Hi,

die meisten kennen ja vermutlich das Konzept. Einfaches Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
void foo()
{
  WaitCursorObject wco;
  someComplicatedOperations();
  finalize();
}


Wie kann ich dieses Konzept aber weiterhin nutzen, wenn ich z.B. so eine Architektur habe:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void foo()
{
  // WaitCursorObject wco; ?
  showWaitCursort();

  // so kompliziert, dass es intern einen Berechnungsthread startet oder auf irgendeinem anderen
  // Weg asynchrone Arbeit verrichtet
  someComplicatedOperations();

  // wco geht out of scope und setzt den Cursor in seinem Destruktor wieder zurück.
  // Hat den Vorteil, dass man das manuelle Löschen/Freigeben/Rücksetzen nicht vergisst,
  // wenn man den Scope z.B. außerplanmäßig durch frühere returns oder sogar exceptions
  // verlässt.
}

// die Berechnung benachrichtigt diese Programmebene z.B. per Event, Qt-Signal oder indem die Funktion direkt als Callback aufgerufen wird.
void operationFinished()
{
  finalize();
  showWorkCursor();
}


Wie man sieht, muss ich den Cursor jetzt wieder manuell setzen, kann mich nicht mehr auf den scope-basierten Automatismus verlassen (denn der Scope: foo reicht ja jetzt nicht mehr, der Berechnungsthread läuft höchstwahrscheinlich ja noch im Hintergrund) und bin damit wieder anfällig für Bugs, indem ich das irgendwo falsch mache oder vergesse. Gibt es hier dennoch eine Möglichkeit, irgendwie die Stärke von RAII zu nutzen?

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

2

13.09.2015, 19:23

Scope ist nicht für asynchrone Operationen gedacht, nicht mal für die Laufzeit. Wenn es etwas gibt, dass du speziell mit diesem Pattern abwickeln möchtest, würde das Pattern innerhalb der asynchronen Operation benutzt.

Dein Beispiel ist sowieso auch ein wenig komisch, da ich nicht wirklich ein RAII Objekt sehe..

Erklär sonst mal was du genau und konkret machen möchtest.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

13.09.2015, 21:32

Du könntest dein WaitCursorObject mit Move-Semantik ausstatten und dann in die Asynchrone Operation moven, sodass es dann am Ende des Scope dort drin zerstört wird... ;)

Am besten mal das hier lesen: http://thbecker.net/articles/rvalue_refe…section_01.html

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

4

13.09.2015, 22:20

Ich glaube, hier geht es eigentlich nicht wirklich um RAII, sondern eher darum, dass du im Konstruktor als Cursor den "Busy"-Cursor setzt und im Destruktor diesen wieder zurücksetzt, oder?
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

13.09.2015, 22:22

Und inwiefern ist der Cursor keine Ressource? ;)

6

14.09.2015, 11:10

@drakon: Das ist aber auch nur begrenzt möglich bzw. wird designtechnisch dann ziemlich hässlich, denn die asynchrone Operation ist in dem Fall reine Berechnungslogik. Damit würde ich dann ja GUI-Zeugs oder sonstige Ressourcen mit reinziehen, was da logisch überhaupt nicht hingehört.

Die Lösung von dot ist auch eine der wenigen, die mir eingefallen ist. Auch dann schickt man zwar GUI-Krempel oder sonstige Ressourcen in die Berechnung, die da nicht wirklich hingehören und hat einen Methodenparameter mehr, der ziemlich nach Krücke aussieht, aber eine bessere Lösung, außer es eben manuell selbst wieder freizugeben, fällt mir auch nicht ein.

Es muss übrigens nicht zwangsläufig ein Cursor sein. Kann auch ein Progress-Dialog, eine Datei, eine Datenbank-Verbindung oder alles andere sein, was man vor der Berechnung allokiert und erst danach wieder freigeben will.

Werbeanzeige