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

Fred

Supermoderator

Beiträge: 2 121

Beruf: Softwareentwickler

  • Private Nachricht senden

31

27.02.2010, 19:49

Zitat von »"CBenni::O"«


Denn - wie gesagt - kann ich einen void* mit delete löschen, aber der Destruktor von dem Objekt wird nicht ausgelöst.


Was sagt uns das? Verwende kein void*.
Void-Zeiger können ziemlich böse sein und C++ bietet deutlich bessere Methoden. Bei dir würde ich eben entweder Vererbung nutzen oder Templates verwenden.

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

32

27.02.2010, 20:54

Zitat von »"drakon"«

Zitat

Denn - wie gesagt - kann ich einen void* mit delete löschen, aber der Destruktor von dem Objekt wird nicht ausgelöst.
static_cast bringt abhilfe, doch dazu muss ich mir merken, welcher Datentyp die Resource ursprünglich hatte.
Hat jemand einen Lösungsvorschlag?

void Zeiger sind C Varianten. Mach einfach eine Basisklasse, von der alle Ressourcen vererbt sind mit einem virtuellen Destruktor. Das ist der Weg, wie man sowas in C++ macht.

Ja, aber auch bei vererbung muss man casten, wenn man die Basisklasse als Typ verwendet... Ich haber das ausprobiert; der Destruktor der Basisklasse wurde aufgerufen, der der abgeleiteten Klasse aber nicht!
Zudem geht jede menge Benutzerfreundlichkeit verloren, da man für jeden neuen Resourcentyp eine neue abgeleitete Klasse erstellen muss...

Und templates? Da stellt sich wieder die Frage mit der Speicherung, da du nicht so etwas machen kannst:

C-/C++-Quelltext

1
2
3
4
5
6
7
template<typename T>
class Resource
{
// ...

};

std::map<std::string, Resource> MyResources;


Aber ich habe eine Idee: Statt nur einer Loader-funktion übergebe ich einen Funktionszeiger, der einen void* in den gewünschten Typ konvertiert, oder kann man tatsächlich einen Typen "in einer Variablen" oder so speichern?

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

idontknow

unregistriert

33

27.02.2010, 21:21

Ist eigentlich nicht schön, dass der User mit void* arbeiten und scih merken muss, was auf was für einen Typ der zeiger gerade zeigt!

Du kannst doch in deinem Manager seperate Methoden für jeden Resourcen Typ schreiben!

Ich denke dabei an sowas:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Manager
{
   template <typename T>
   bool Load<Image>(std::string path);

   template <typename T>
   bool Load<Sound>(std::string path);
   
   template <typename T>
   Image* Get<Image>(std::string path);

   std::map<std::string, void*> m_Resources;
}


}

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

34

27.02.2010, 21:26

Der User würde es ja auch nur bei der Initialisierung mitbekommen... und eine Modifizierung Userseits ist relativ schlecht, da der Manager später mal in mein Framework aufgenommen werden soll...

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

35

28.02.2010, 15:21

Zitat von »"CBenni::O"«


Ja, aber auch bei vererbung muss man casten, wenn man die Basisklasse als Typ verwendet... Ich haber das ausprobiert; der Destruktor der Basisklasse wurde aufgerufen, der der abgeleiteten Klasse aber nicht!
Zudem geht jede menge Benutzerfreundlichkeit verloren, da man für jeden neuen Resourcentyp eine neue abgeleitete Klasse erstellen muss...

Nein. Dann hast du etwas falsch gemacht. Wenn du die Basisklasse so implementierst:

C-/C++-Quelltext

1
2
3
4
struct base
{
  virtual ~base () {}
};



Dann wird auch der Destruktor der abgeleiteten Klasse aufgerufen.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

struct base
{
    virtual ~base () { std::cout << "base::~base()\n"; }
};

struct a : base 
{
    ~a () { std::cout << "a::~a ()"; }
};

int main() 
{
    a a_;
}

Gibt wie erwartet "a::~a() base::~base()" aus.

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

36

28.02.2010, 15:43

Ja, es hat soweit geklappt, aber nun stürtzt das Programm am Programmende immer ab, wenn ich sf::Music verwende
Woran könnte das liegen?
Ich habe - trotz debugger und einzelschritt-modus (er sagt, dass er für die entsprechende stelle keinen Quellcode hat; der Assemblercode liegt innerhalb einer OpenAl-Dll) - keinen blassen schimmer warum.
Ich werde mal einen projektordner hochladen...

Und mit dem Laden klappt das auch noch nicht so ganz...

mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

37

28.02.2010, 16:15

Ich vermute mal, dass du irgendwo Speicher 2x frei gibst..

CBenni::O

1x Contest-Sieger

  • »CBenni::O« ist der Autor dieses Themas

Beiträge: 1 145

Wohnort: Stuttgart

  • Private Nachricht senden

38

28.02.2010, 16:21

Inwiefern ist das gefährlich?

C-/C++-Quelltext

1
2
3
4
class foo;
foo* bar = new bar;
delete bar;
delete bar; // Macht doch nichts, oder?


mfg CBenni::O
Ein Mitglied der VEGeiCoUndGraSonMaWiGeS Bewegung.
42!
Aufräumen kann jeder, nur das Genie überblickt das Chaos!
Metal will never die!
1. Sppro Gamecontest - mein Beitrag

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

39

28.02.2010, 16:51

Nein. Das undefiniert und führt wahrscheinlich zu einem Fehler.

Die Runtime weiss ja nicht, ob der Speicher schon freigegeben wurde, oder nicht.

Was ungefährlich ist, delete 0 zu haben. Da passiert nichts, aber einen bereits freigegebenen Speicher zu zerstören ist böse.

idontknow

unregistriert

40

28.02.2010, 16:57

Daher auch der ganze Pseudo Safe Delete Kram, der jeden Pointer auf 0 setzt um eben genau das zu verhindern.

Ob das sinnvoll ist muss man denke ich selber entscheiden :).

Werbeanzeige