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

22.06.2014, 19:02

C++ Reference Counting

Liebe Community,

ich habe momentan eine Frage bzgl. der Verwaltung nativer Ressourcen in C++. Als Beispiel sollen hier Texturen in OpenGL dienen. Wenn man die Texturen nun in Klassenwrappern umsetzt, ist es sinnvoll diesen Klassen auch Reference Counting Funktionen hinzuzufügen, oder ist das unnötiger Overhead? Momentan habe ich in jeder Klasse, welche eine native Ressource verwaltet solche Funktionen eingebaut, die bei Aufruf des Destruktors prüfen, ob die Instanz die letzte Referenz auf die Ressource hält, und wenn ja selbige Ressource freigeben. Meine Frage: Wie sinnvoll ist das?

Liebe Grüße,
~ EuadeLuxe ~

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

22.06.2014, 19:20

Um mal das Beispiel der Texturen aufzugreifen.
Stell dir vor, du hast einen Objekttyp (Klasse) "Geschoss", der beim Erzeugen eine entsprechende Textur lädt und sie beim Zerstören wieder freigibt.
Nun könnte es passieren, wenn man immer nur einzelne Schüsse abfeuert, dass diese Geschoss-Textur ständig neu geladen und wieder freigegeben wird.
Ja, es ist schon sinnvoll zu wissen, ob eine Ressource momentan irgendwo benötigt wird.
Wenn das nicht mehr der Fall ist, würde ich die Ressource aber nicht sofort freigeben, denn womöglich wird sie gleich wieder gebraucht. Freigeben kannst du immer noch, wenn z.B. die Ressource eine bestimmte Zeit lang nicht gebraucht wurde oder der Speicher knapp wird.

3

22.06.2014, 19:23

Nun, das heißt generell bietet sich hier ein Ressourcen-Manager an. Ist es dann aber überhaupt noch sinnvoll Reference Counting zu betreiben?

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

4

22.06.2014, 19:35

Smartpointer machen das gleiche. Ja ist sinnvoll, ich würds aber nicht selbst implementieren.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

5

22.06.2014, 19:44

Wie gesagt, es ist schon wichtig zu wissen, ob man eine Ressource gefahrlos freigeben kann.

6

22.06.2014, 19:53

D.h. es ist zumindest nicht "einfach nur sinnentleert" die Ressourcen sich auch noch zum Teil selbst verwalten zu lassen? Man kann ja zum Beispiel im Ressourcen-Manager immer eine Kopie (d.h. im Endeffekt eine Referenz) in einer Map, o.Ä. speichern, sodass die Ressource auf jeden Fall nicht freigegeben wird. Und wenn man will kann man ja den Ressourcen-Manager auch nur Zeiger ausgeben lassen, sodass er im Endeffekt immer noch frei ist, zu bestimmen, wann eine Ressource effektiv freigegeben wird.

Dann gleich noch eine Frage: Wie sinnvoll ist es einer Ressourcen verwaltenden Klasse eine "Dispose()"-Methode zu geben, d.h. eine Methode, die die verwaltete Ressource sofort freigibt? Momentan hat bei mir jede dieser Klassen eine solche Methode, da meistens im Destruktor mögliche Exceptions einfach "geschluckt" werden, und ich damit dem Nutzer eine Möglichkeit geben möchte, diese Exceptions abzufangen (Eine solche Exception kann ja sogar schon ominöserweise beim Freigeben von dynamisch alloziiertem Speicher auftreten). Ich sehe gerade laut Scott Meyers ist das wohl Gang und Gebe, aber so ganz überzeugt bin ich davon einfach nicht.

Evrey

Treue Seele

Beiträge: 245

Beruf: Weltherrscher

  • Private Nachricht senden

7

22.06.2014, 19:56

Cache doch einfach die std::shared_ptr zu Objekten, die du erst später entfernen willst.

C-/C++-Quelltext

1
2
3
4
int main(int _argc, char** _argv) noexcept {
  asm volatile("lock cmpxchg8b %eax");
  return 0;
} // ::main
(Dieses kleine Biest vermochte einst x86-Prozessoren lahm zu legen.)

=> Und er blogt unter Hackish.Codes D:

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

8

22.06.2014, 20:23

Jup so mache ich es auch.

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

9

22.06.2014, 20:39

Jep, selber schreiben muss man sowas heute eigentlich nur noch zu akademischen Zwecken. Ansonsten gibt es ja den shared_ptr. Aber bei dem denke ich mir, dass man ihn nur so selten wie möglich und nur wo wirklich nötig benutzen. Er hat halt einen kleinen Overhead gegenüber einem unique_ptr.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

10

22.06.2014, 20:59

Okay, dann nehme ich das mal als Antwort. Bezüglich der 2. Frage: Wie stellt eigentlich std::shared_ptr sicher, dass der Speicher unter ALLEN UMSTÄNDEN freigegeben wird, auch wenn eine Exception passiert? In der Implementierung für den GCC konnte ich leider nichts aufschlussreiches finden.

Werbeanzeige