Regel der großen Drei
-
Hallo
Ich habe eine Klasse mit einem Zeiger auf eine SDL_Surface* p_screen. Diese wird der SDL-funktion SDL_setVideoMode() gefüllt. Was heißt das nun für mich?
chrische
-
Wird tatsächlich für jedes Objekt SetVideoMode aufgerufen? Das ist imho nicht besonders sinnvoll, denn die Zeiger in den anderen Objekten werden damit ungültig...
=> Regel nicht verletzt, da die Daten kopiert werden können sollten.PS: Wie wärs mit einem Singleton für den Zugriff auf die Framebuffer-Oberfläche?
-
Hallo
Okay, ich habe meine Situation verkürzt dargestellt. Ich habe ein singleton namens framework, welches eine Membervariable p_screen vom Typ SDL_Surface* hat. In der Init-Funktion wird diese mittels SDL_SetVideoMode() gefüllt. In einer Spriteklasse habe ich ebenfalls einen Membervariable mit dem Namen p_screen und auch vom Typ SDL_Surface*. In deren Init-Funktion wird diese Varaibel mit der des frameworks gefüllt, damit die Bilder auch immer auf der richtigen surface landen. Nun lautet die Frage muss ich in der sprite-Klasse wirklich alle drei Funktionen überschreiben oder reicht nicht Zuweisungs- und Copykonstruktor?
chrische
-
Nein. Das würde dir nicht helfen. Ich denke, du solltest die Oberfläche /immer/ vom Singleton holen, wenn du auf sie zugreifst anstatt sie in jedem Sprite zu speichern (vorausgesetzt, sie wird wirklich immer so initialisiert wie du es dargestellt hast). Ansonsten gilt weiterhin:
=> Regel nicht verletzt, da die Daten kopiert werden können sollten.
-
Hallo
Warum solltet es Sinn machen bei jeden render Vorgang den screen zu holen, wenn ich die Möglichkeit habe diesen Funktionsaufruf nur einmal in der init-Funktion zu machen?
chrische
-
Du holst dir nur einen Zeiger. Der Mehraufwand (zwei sehr leicht wegzuoptimierende Methodenaufrufe) sollte gegen 0 gehen, je nach benutzter Singleton-Variante. Und zusätzlich hast du die Möglichkeit gewonnen, bei Bedarf die Auflösung zu ändern. Falls du das eh nicht brauchst, existiert überhaupt kein Problem, vor allem auch keine Verletzung der Regel

-
Hallo
Ich glaube mein Denkfehler war, dass man immer, wenn man einen Zeiger als Member hat, man dann auch einen Copyc'tor braucht. Das scheint aber nur der Fall zu sein, wenn ich diesen selber mittels new anfordere, weil dann nach der Kopie zwei Zeiger auf denselben Speicherbereich zeigen udn wenn nun eine Kopie gelöscht wird, dann kracht es. Wenn ich den Zeiger nicht mit new anfordere, brauche ich also auch keinen copxc'tor?
crische
-
Wenn du einen Zeiger nicht mit new anforderst (direkt oder indirekt), dann wird der zum Zeiger gehoerende Speicher anderweitig verwaltet. Dann brauchst du auch keinen Destruktor, der delete aufruft, und dann ist das Kopieren des Zeigers meist auch kein Problem, weil der Destruktr ja auch nichts kaputt macht, worauf andere Objekte noch zeigen koennten.
Du solltest aber sicherstellen, dass das Objekt, das den Speicher verwaltet (vermutlich das, von dem du den Zeiger bekommst), mindestens solange lebt wie die Objekte, die den Zeiger beinhalten oder zumindest so lange wie sie ihn nutzen.Die Regel besagt ja auch nicht, dass du die drei definieren musst, wenn du einen Zeiger in der Klasse hast, sondern dann, wenn die Klasse eigene Ressourcen verwalten muss, z.B. Speicher, den sie selber anfordert (in dem Fall hat sie natuerlich auch Zeiger auf den Speicher), irgendwelche Sockets oder andere Ressourcen. Deshalb sind Zeiger in der Klasse ein Indiz dass man mal nachschauen sollte ob man die drie nicht braucht, aber Zeiger zwingen dich nicht auf jeden Fall zur Definition der drei.
-
Hi,
ich gebe auch mal meinen Senf dazu.
Ich glaube, auf eine einfache Formel kann man das nicht wirklich bringen. Man muss sich imer überlegen, was "Kopieren" bedeutet - und wogegen man sich ggf. absichern möchte. Auch wenn man einen Zeiger nur als "Verweis auf ein anderes Objekt" aggregiert, kann das Kopieren zu Problemen führen:struct A { A() : i(0) {} A(int* p) : i(p) {} int* i; }; int main (int argc, char **argv) { A a1; { int i=0; A a2(&i); a1 = a2; } cout << a1->i; // Hupps !!! return 0; }Man MUSS sich gegen sowas nicht absichern (mache ich auch meistens nicht), aber es ist einfach eine "Falle", in die man laufen kann.
Gruß,
Simon2.
-
Deswegen sagte ich ja, dass man sicherstellen solte, dass das Objekt, das die Ressource verwaltet (in dem Fall dein int i im inneren scope bzw. der scope selber) mindestens so lange lebt wie die Objekte, die ueber ihre memberzeiger darauf zugreifen wollen. was hier eindeutig nicht der Fall ist
