Hallo Markus Gögele
Korrekt, du gibst im Destruktor der loop-Klasse die aktuelle rect und color Variabeln frei, allerdings alle anderen in draw_scene durch new_color und new_rect allozierten Versionen nicht. Zudem wird der Destruktor aufgerufen wenn man das Spiel beendet, neuer Speicher wird jedoch in jedem Durchgang des Frames alloziert.
Wo wir nun aber gerade schon beim Thema sind:
Du verwendest C++ und du arbeitest direkt mit Zeigern (rectangle*, color*). Das beisst sich eigentlich. Zeiger sind ein Relikt aus C-Zeiten (genau so wie Arrays) und sollten nicht mehr verwendet werden.
In deinem Fall sähe das zum Beispiel so aus:
In der Loop-Klasse sind new_color und new_rect modifiziert:
die Member col und rect der Klasse brauchst du nicht mehr und auch im Destruktor musst du nichts freigeben.
Diese Methoden sehen dann implementiert so aus:
Ich habe den Klassen color und rectangle entsprechende Konstruktoren hinzugefügt damit es bisschen einfacher geht.
Und entsprechend ändert sich dann auch draw_scene:
Damit das ganze auch sauber mit der graphics-Klasse läuft werden auch deren Parameter angepasst:
entsprechend auch in der Implementation, das lass ich aber weg, du musst da ja nur die Parameterliste anpassen.
Für deine Anwendung war jetzt unique_ptr noch das richtige für new_color und new_rect, allerdings gibt es auch noch andere Varianten wie weak_ptr oder shared_ptr. Du musst je nach Einsatzgebiet schauen welches für dich der richtige ist, sie stechen alle jedoch immer die raw-Pointer aus in C++.
Grüsse
Cromon
Korrekt, du gibst im Destruktor der loop-Klasse die aktuelle rect und color Variabeln frei, allerdings alle anderen in draw_scene durch new_color und new_rect allozierten Versionen nicht. Zudem wird der Destruktor aufgerufen wenn man das Spiel beendet, neuer Speicher wird jedoch in jedem Durchgang des Frames alloziert.
Wo wir nun aber gerade schon beim Thema sind:
Du verwendest C++ und du arbeitest direkt mit Zeigern (rectangle*, color*). Das beisst sich eigentlich. Zeiger sind ein Relikt aus C-Zeiten (genau so wie Arrays) und sollten nicht mehr verwendet werden.
In deinem Fall sähe das zum Beispiel so aus:
In der Loop-Klasse sind new_color und new_rect modifiziert:
C++:
std::unique_ptr<rectangle> new_rect( int x, int y, int width, int height, int depth_index = -1);
std::unique_ptr<color> new_color( float r, float g, float b );
die Member col und rect der Klasse brauchst du nicht mehr und auch im Destruktor musst du nichts freigeben.
Diese Methoden sehen dann implementiert so aus:
C++:
std::unique_ptr<rectangle> loop::new_rect( int x, int y, int width, int height, int depth_index)
{
return std::unique_ptr<rectangle>(new rectangle(x, y, width, height, depth_index));
}
std::unique_ptr<color> loop::new_color( float r, float g, float b )
{
return std::unique_ptr<color>(new color(r, g, b));
}
Ich habe den Klassen color und rectangle entsprechende Konstruktoren hinzugefügt damit es bisschen einfacher geht.
Und entsprechend ändert sich dann auch draw_scene:
C++:
for(int i=0; i<10; i++)
{
for(int j=0; j<10; j++)
{
std::unique_ptr<color> colorPtr;
if(map[i][j] == 1)
{
colorPtr = new_color( 1.0f, 0.0f, 0.0f );
}else{
colorPtr = new_color( 1.0f - 0.025f * i, 1.0f - 0.025f * j, 1.0f - 0.025f * j - 0.025f * i );
}
auto rectPtr = new_rect( i * 32 , j * 32, 32, 32, -5 );
g.fill_rectangle(rectPtr, colorPtr );
g.draw_rectangle( rectPtr, new_color( 1.0f, 0.0f, 0.0f ) );
}
}
Damit das ganze auch sauber mit der graphics-Klasse läuft werden auch deren Parameter angepasst:
C++:
void draw_rectangle( const std::unique_ptr<rectangle>& rect, const std::unique_ptr<color>& col, float width = 1 );
void draw_ellipse( const std::unique_ptr<rectangle>& rect, const std::unique_ptr<color>& col, float width = 1 );
void fill_rectangle( const std::unique_ptr<rectangle>& rect, const std::unique_ptr<color>& col);
void fill_ellipse( const std::unique_ptr<rectangle>& rect, const std::unique_ptr<color>& col);
entsprechend auch in der Implementation, das lass ich aber weg, du musst da ja nur die Parameterliste anpassen.
Für deine Anwendung war jetzt unique_ptr noch das richtige für new_color und new_rect, allerdings gibt es auch noch andere Varianten wie weak_ptr oder shared_ptr. Du musst je nach Einsatzgebiet schauen welches für dich der richtige ist, sie stechen alle jedoch immer die raw-Pointer aus in C++.
Grüsse
Cromon