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

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

1

12.01.2013, 22:56

Im Destruktor aufräumen, kein Release(); mehr nötig?

Hallo zusammen.
Da ich ein von natur aus fauler Mensch bin kam ich neulich auf folgende Idee:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class GibMichWiederFrei {

    // code....
    // dynamischer Speicher wird verwendet usw..
    // COM Interfaces -> Referenzzähler

    // Und jetzt soll einfach alles der Destruktur regeln
    ~GibMichWiederFrei() {
            // neu im C++11 standard: nullptr, unser neuer Freund
            if( nullptr != m_lpDevice)  { // oder sowas 
                // "Guck ob da was initialisiert ist. Wenn ja, fahrs runter!"
                m_lpDevice->Release();
            }
};


Das hat bisher prima funktioniert, doch langsam kommen mir Zweifel auf, ob das eine so gute Idee ist.
Speziell wenn man mit Dateistreams arbeitet, sind die Ergebnisse äußerst rätselhaft.
Ich hab halt in jeder Klasse noch ein Release(); eingebaut, falls ich das mal manuell aufrufen will.
Der Konstruktor ist soweit ich weis nicht zeitbegrenzt, soll heißen: Ich hab kein Zeitlimit zum "aufräumen", oder?

Was meint ihre denn dazu`?
Liebe Grüße Johannes Schneider
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

2

12.01.2013, 23:17

Das hat bisher prima funktioniert, doch langsam kommen mir Zweifel auf, ob das eine so gute Idee ist.


Doch, das ist i.A. eine sehr gute Idee und auch ein bekanntes C++ Idiom.
@D13_Dreinig

  • »Johannes Schneider« ist der Autor dieses Themas

Beiträge: 103

Beruf: Chemiestudent

  • Private Nachricht senden

3

12.01.2013, 23:27

"Fifty years of programming language research, and we end up with C++?"
Richard O'Keefe :P

Ne aber mal im Ernst sollte das nicht absolut sauber und fehlerfrei sein?
"Das Glück des Forschers besteht nicht darin, die Wahrheit zu besitzen, sondern eine Wahrheit zu erringen. Und in diesem fortschreitendem, erfolgreichen Suchen nach der Wahrheit - darin liegt die
eigentliche Befriedigung." Max Planck

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

4

12.01.2013, 23:30

Ne aber mal im Ernst sollte das nicht absolut sauber und fehlerfrei sein?


Doch klar, die Technik ist bekannt unter RAII und findet breite Anwendung, z.B. in Form von Smartpointern (std::auto_ptr, std::shared_ptr) oder eben auch COM-Spezifisch fürs Referenzenzählen ComPtr
@D13_Dreinig

5

13.01.2013, 08:19

Aber es ist IMO kein RAII mehr, wenn man trotzdem noch eine manuelle Release-Funktion hat. Weil sobald man die aufruft hat man ja ein Objekt, dass man nicht mehr wirklich benutzen kann, was genau das ist, was man mit RAII vermeiden wollte.
Lieber dumm fragen, als dumm bleiben!

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

13.01.2013, 08:43

Aber es ist IMO kein RAII mehr, wenn man trotzdem noch eine manuelle Release-Funktion hat.


Vielleicht kein RAII mehr in seiner reinsten Form? :)
@D13_Dreinig

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

7

13.01.2013, 12:11

Ich würde sogar sagen, den Destruktor zu benutzen ist eine sehr gute Idee und deine manuelle Release-Funktionen eine sehr miese ...
(Bei COM-Objekten muss man natürlich Release aufrufen, die arbeiten ja auch mit Refcounting)
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

8

13.01.2013, 12:53

Ich weiß nicht, ob Du da schon vorgesorgt hast, aber zur Sicherheit: Du musst bei dieser Klasse dann auch an ordentliche Kopier- und (C++11)-Bewegungsbehandlung denken. Immer, wenn die Klasse einen Com-Zeiger bekommt, muss sie dessen Referenzzähler erhöhen. Und wenn die Klasse rumkopiert wird, muss sie das auch tun. Sonst gibt evtl. ein altes Objekt dieser Klasse das Com-Objekt schon frei, obwohl vorher eine Kopie des Objekts angefertigt wurde und die natürlich noch einen weiteren Zeiger auf das Com-Objekt enthält.

Wenn Du das alles bedacht hast, hast Du wahrscheinlich einfach nur den Code von ComPtr dupliziert. Irgendwer vor Dir hat da nämlich auch schon dran gedacht. Aber ich weiß grade nicht, wo man den ComPtr findet.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

H5::

Treue Seele

Beiträge: 368

Wohnort: Kiel

  • Private Nachricht senden

9

20.01.2013, 05:59

Da du ja scheinbar mit COM Objekten arbeitest kannst du dir ja auch mal die Funktion der Deleter (komisches Wort) ansehen. Damit kannst du das normale Verhalten beim Zerstören eines Heap-Objetes ersetzen. So, dass anstatt delete xyz; xyz->Release(); verwendet wird. Dann kannst du dir das Ganze im Destruktor sparen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//Beispiel Deleter für COM Objekte 
class COMDeleter 
{ 
public: 
   template<typename T> 
   auto operator()(T* t) 
      -> void 
   { 
      if(t != nullptr) 
      { 
          t->Release(); 
      } 
   } 
};




C-/C++-Quelltext

1
2
3
4
// Anwendung mit einem std::unique_ptr. 
ID3D11Resource* resource_p = nullptr; 
... 
std::unique_ptr<ID3D11Resource, COMDeleter> resource(resource_p);


Ähnlich kann man es auch mit dem shared_ptr machen. Dann hat man auch einen Ref. Zähler usw.
:love: := Go;

Werbeanzeige