Member als Zeiger oder "normal"?
-
Hi,
Mal wieder ne Strukturfrage:
Was ist besser, member einer Klasse als Zeiger oder als Objekte zu deklarieren? Unabhänig davon ob die member nur intern gebraucht werden (also im Konstruktor erzeugt werden) oder im Konstruktor gesetzt werden.class Foo { private: Foo Foo1; Foo *Foo2; //... };Danke!
-
Wenn du keinen besonderen Grund hast, einen Pointer zu verwenden, dann lass es. Dann sparst du dir auch das Reservieren und Freigeben von Speicher.
-
Erstens mal werden alle Member einer Klasse im Konstruktor erzeugt.
Zweitens spielt es schon eine Rolle, ob das Objekt nur intern benötigt wird oder nicht (wobei sich das eher auf die Speicheranforderung bezieht).Normalerweise werden Objekte als Member benutzt. Sie sind leicht zu handhaben und benötigen keine eigene Implementierung der Grossen Drei. Wenn man allerdings sehr grosse Objekte erstellt oder die Speicherverwaltung selbst in die Hand nehmen will, sind Zeiger angebracht. Oder wenn die Zeiger auf externe Objekte verweisen, für die die Klasse nicht zuständig ist.
-
Inwiefern benötigen interne gebrauchte Objekte mehr/weniger Speicher als extern gebrauchte Nexus?
Ich sah das gerade nur bei wxWidgets Beispielcode, dass in Anwendungen oft mit pointern gearbeitet wird und sah da kein speziellen Vorteil für, da man ja eigentlich nie irgendwelche Buttons oder Ähnliches an einer andere Anwendung/Klasse übergibt.
-
Mit "Speicheranforderung" meinte ich nicht die Menge angeforderten Speichers, sondern vielmehr die Verantwortung dafür.

Wenn man einen Zeiger als Member hat, muss der referenzierte Speicherbereich nicht zwingend zum Besitz der Klasse gehören (sprich: die Klasse ist für Speicherverwaltung zuständig). Der Zeiger kann gerade so gut als Verweis dienen (auf externe Objekte, deren Speicher auch extern verwaltet wird), was z.B. ein Objekt als Member nicht kann.
-
Ahso, ja es ergibt Sinn

Bzw. es ergibt eigentlich keinen Sinn für Buttons oder ähnliches pointer zu nutzen wenn man diese nie an ein andere Objekt übergibt.
-
Naja, kommt wieder drauf an...

Man kann es einfach nicht ganz pauschal sagen. Und ich kenne den Kontext zu wenig, um das zu beurteilen (abgesehen davon bin ich auch nicht gerade der Design-Master :)). Wobei es generell nicht unbedingt ratsam ist, fremden Code als richtig anzusehen und sich daran zu orientieren...

Wenn man Daten aus irgendeinem Grund auf dem Heap haben will, sie für Polymorphie oder manuelle Speicherverwaltung benötigt, wäre ein Zeiger vielleicht angebracht. Oder eben für Verweise (wobei man da auch Referenzen in Betracht ziehen kann). Man ist mit Zeigern halt flexibler als mit Objekten selber, aber es birgt auch Gefahren und kann zu schwer auffindbaren Fehlern führen.
Ein ganz wichtiger Vorteil, der mir erst gerade wieder eingefallen ist, ist die Verkleinerung von Abhängigkeiten. Wenn man modular programmiert und in der Klassendefinition nur Zeiger hat, müssen im Header nicht bereits alle Datentypen vollständig definiert sein. Es reicht, wenn man die entsprechenden Header in der Implementierungsdatei inkludiert.
-
Pille456 schrieb:
Ich sah das gerade nur bei wxWidgets Beispielcode, dass in Anwendungen oft mit pointern gearbeitet wird und sah da kein speziellen Vorteil für, da man ja eigentlich nie irgendwelche Buttons oder Ähnliches an einer andere Anwendung/Klasse übergibt.
Pille456 schrieb:
Bzw. es ergibt eigentlich keinen Sinn für Buttons oder ähnliches pointer zu nutzen wenn man diese nie an ein andere Objekt übergibt.
Jetzt bist du schon weiter als die Entwickler von wxWidgets. Die Entwickler hinter wxWidgets sind ... naja ... ich würde sagen etwas veraltet. Die Bibliothek ist allgemein nicht so der C++ Knüller.
Sie ist natürlich auch schon etwas älter, aber es scheint nicht, dass die Entwickler auf neue Features und Ideen von C++ eingehen möchten.Das Problem in dem Fall bei wxWidgets ist, dass es zu jedem Fensterobjekt einen Referenzzähler gibt, welcher das Objekt am Ende automatisch mit
deletelöscht. Dadurch kannst du kein solches Objekt auf dem Stack ablegen, da sonst eindeleteauf einen Stackzeiger aufgerufen würde, was zu undefiniertem Verhalten führt und meistens zum Absturz. Gleiches gilt als Memberobjekt, da auch eindeleteauf einen Zeiger von einem Memberobjekt nicht definiertes Verhalten ist.
wxWidgets Fensterobjekte müssen daher immer pernewerstellt werden und man hat somit immer Zeiger.Es gibt Ausnahmen, aber eigentlich sollte es genau umgekehrt sein, also das die Ausnahmen die Regel sind und die Regel die Ausnahme ...

Grüssli
PS: Das ist natürlich eine persönliche Meinung, falls hier jemand wxWidgets mag

-
Das ist natürlich eine persönliche Meinung, falls hier jemand wxWidgets mag
Nur weil man wxWidgets mag heißt das nicht, dass man den Coding Style mag.
wxWidgets ist eine der besten freien GUI Libs, weil die Alternativen einfach nicht so berauschend sind. Da akzeptiert man dann auch mal den veralteten Style in seinen GUI Klassen.
-
blubb schrieb:
Das ist natürlich eine persönliche Meinung, falls hier jemand wxWidgets mag
Nur weil man wxWidgets mag heißt das nicht, dass man den Coding Style mag.
wxWidgets ist eine der besten freien GUI Libs, weil die Alternativen einfach nicht so berauschend sind. Da akzeptiert man dann auch mal den veralteten Style in seinen GUI Klassen.Das war eigentlich an Leute gerichtet, welche sich wehement dagegen wehren. Deshalb auch der Smilie, sonst hätte ich den nicht hingetan. Wahrscheinlich nicht mal das PS, da es eigentlich klar ist, dass dies eine Meinung ist.
Gibt viele, welche wxWidgets für eine verdammt gut programmierte C++ Bibliothek halten, musste das nun schon ein paar mal erleben. Hab da teilweise ganz böse Antworten bekommen, dass ich nicht wüsste, wovon ich rede und doch einfach gar keine Ahnung habe.Ich selber verwende im übrigen auch wxWidgets, weil es irgendwie keine wirklich besseren Alternativen gibt, mit entsprechender Dokumentation, Stabilität und Support.
Grüssli