Pointer: Wann und wozu?



  • trax1988 schrieb:

    @Volkard
    Das würde bedeuten: Wenn ich Objekte erzeuge, von denen mir deren Inhalt klar ist kann ich sie auch ohne Pointer erzeugen. Wenn ich aber zur Lautzeit Objekte (Speicher) freigeben will, der sich auf Objekte bezieht, sollte ich diese mit Pointer erzeugen und später freigeben?

    Ich kann die Bedeutung dieses Satzes nicht deuten. Falls er darauf abzielt, eine Stilregel zu finden, die sagt, Zeiger häufiger zu verwenden, als dringend nötig, dann sage ich mal: Nein.



  • trax1988 schrieb:

    1. Nun, ich habe gelesen, dass man globale Variablen immer vermeiden sollte, da sie schlichtweg keinen guten Stil bieten und "öffentlich" sind und somit für jeden zugänglich.

    Da hast du recht, aber das hat mit Pointern nichts zu tun.



  • Pointer auf Objekte haben u.a. den Vorteil, das die Objekte auf dem Heap liegen. Der ist im alg. größer als der Stack. Das merkt man z.B. dann, wenn man mal rekursiv eine sehr große Menge an Objekt, angelegt auf dem Stack, in eine Liste oder ähnliches packt. Der Nachteil ist, dass man für das 'zerstören' zuständig ist. Dieses kann aber durch die Verwendung von 'smart pointer' entschärft werden.
    Gruß



  • Darf man Fragen mit was du lernst, z.B. was für ein Buch?

    In C++ verwendet man rohe Zeiger/Arrays nur dann, wenn man sie wirklich braucht. Ist dies nicht der Fall, solltest du sog. Container nehmen.
    Ich hab mal noch ein paar Zitate gefunden: (ich denke mal, das geht für die hier zitierten Personen in Ordnung. :))

    ipsec schrieb:

    Die ganze Problematik enthält viele Fallstricke, so dass ich dir rate, rohe Arrays und rohes new und delete am besten gar nicht zu verwenden, sondern auf Klassen der Standardbibliothek (hier z.B. vector ) zurückzugreifen.

    Nexus schrieb:

    Ja, Arrays sind wegen ihrer "Features" recht mühsam. Glücklicherweise behebt std::array fast alle Probleme (Kopiersemantik, Debug-Range-Checks, kein Array-To-Pointer-Decay, Methode für Grösse, ...).
    Ich verwende eigentlich nie mehr rohe Arrays.Die STL (ich zähle std::array mal dazu) hat auf Vieles eine Antwort.

    pumuckl schrieb:

    Einige Dinge, die bei C noch unter "Grundlagen" laufen, sind bei C++ eher "Details für Fortgeschrittene". Das heißt, es kann durchaus vorkommen, dass man schon eine Weile C++ lernt und mit der STL per Du ist, bevor man sich mit low-level Pointerfrickeleien und C-Strings auseinandersetzt, die in C zum täglich Brot gehören und einem in den ersten Monaten in Fleisch und Blut übergehen müssen.

    314159265358979 schrieb:

    Allerdings solltest du rohe Arrays in C++ nicht verwenden, es sei denn, du hast einen guten Grund dafür.



  • Helmut.Jakoby schrieb:

    Pointer auf Objekte haben u.a. den Vorteil, das die Objekte auf dem Heap liegen.

    Du vermischst gerade zwei Konzepte – Zeiger und Speicherverwaltung. Man kann sehr wohl Zeiger haben, ohne Speicher manuell zu verwalten. Das ist auch ein sinnvoller Anwendungszweck von Zeigern. Um Speicherverwaltung wegzukapseln, gibt es RAII (am wichtigsten sind Container und Smart-Pointer).



  • Ich sollte also kein Array von Objekten erzeugen, sondern diese in einem Container erzeugen.

    Ich habe zu den Pointer noch eine Frage: Wenn ich nun eine Klasse definiere und ich z.B. einen... Titel fesetsetzen möchte, so kann die Größe doch variabel sein. Ist es dort sinnvoller einen Pointer zu verwenden oder einfach die Größe beim anlegen durch den Konstruktor festzusetzen?

    EDIT: Bei einem Objekt-Array dann einfach ein Vektor-Container verwenden oder kann man diesen auch typisieren?



  • trax1988 schrieb:

    Ich sollte also kein Array von Objekten erzeugen, sondern diese in einem Container erzeugen.

    Ja.
    Kein Problem, wenn Du dem Buch folgst und anfangs mal Arrays benutzt. Aber spaäter gehts in Richtung std::vector und std::array. Wenn Du das im Hinterkopf hast, ist alles im Lot.

    trax1988 schrieb:

    Ich habe zu den Pointer noch eine Frage: Wenn ich nun eine Klasse definiere und ich z.B. einen... Titel fesetsetzen möchte, so kann die Größe doch variabel sein. Ist es dort sinnvoller einen Pointer zu verwenden oder einfach die Größe beim anlegen durch den Konstruktor festzusetzen?

    Pointer. Also nee, Pointer wäre zwar richtig, aber RAII ist noch wichtiger. Um den Pointer eine Klasse basten, die genau das macht, daß Du nicht mehr selber delete aufrufen mußt. Ach, die gibt's für Titel natürlich auch schon. std::string heißt sie.

    trax1988 schrieb:

    Bei einem Objekt-Array dann einfach ein Vektor-Container verwenden oder kann man diesen auch typisieren?

    vector<DeineKlasse>//gut
    bzw
    vector<DeineKlasse*>//nicht so gut, aber bei Vererbung nötig
    irgendwo gabs für den zweiten Fall sowas wie Pointer-Container, die sind wieder gut.



  • trax1988 schrieb:

    Ich habe zu den Pointer noch eine Frage: Wenn ich nun eine Klasse definiere und ich z.B. einen... Titel fesetsetzen möchte, so kann die Größe doch variabel sein. Ist es dort sinnvoller einen Pointer zu verwenden oder einfach die Größe beim anlegen durch den Konstruktor festzusetzen?

    Wenn ich dich richtig verstehe meinst du sowas:

    Klasse objekt("Titel");
    

    Da nimmst du std::string und damit brauchst du dir keine Gedanken über Länge/Größe zu machen.

    trax1988 schrieb:

    EDIT: Bei einem Objekt-Array dann einfach ein Vector-Container verwenden oder kann man diesen auch typisieren?

    Du musst dem Container schon mitteilen, von welchem Typ er Objekte halten soll.
    Z.B.

    vector<int> ganzzahlen;
    

    edit: Für Zeiger nimmst du dann Smart-Pointer:
    http://www.c-plusplus.net/forum/134971
    http://www.c-plusplus.net/forum/284191?highlight=scopedptr



  • Lybrial schrieb:

    Wenn du z.B. eine Methode hast, die einen Parameter übergeben bekommt, den du verändern möchtest, dann ist dieser Wert nur innerhalb der Funktion gültig, außerhalb nicht.
    Das passiert nicht, wenn der übergebene Parameter ein Pointer ist.

    Nur das man unter C++ hier in der Regel eher Referenzen verwendet (Es sei den der Parameter soll optional sein).



  • Ich danke allen für ihre Antworten. Ihr habt mir damit weitergeholfen. Endlich mal kein Forum, in dem man patzige Antworten zu erwarten hat :D.



  • Pointer haben aber gegenüber Referenzen den Vorteil, dass man nicht ausversehen eine Kopie erzeugen kann.

    Foo& give_foo() { ... }
    Foo myFoo = give_foo(); // Coy-Constructor wird getriggert, unmöglich bei Pointer-Rückgabe.
    


  • Ethon schrieb:

    Pointer haben aber gegenüber Referenzen den Vorteil, dass man nicht ausversehen eine Kopie erzeugen kann.

    Foo& give_foo() { ... }
    Foo myFoo = give_foo(); // Coy-Constructor wird getriggert, unmöglich bei Pointer-Rückgabe.
    

    wenn das die gefahr ist, stimmts woanders nicht.



  • Ethon schrieb:

    Pointer haben aber gegenüber Referenzen den Vorteil, dass man nicht ausversehen eine Kopie erzeugen kann.

    Foo& give_foo() { ... }
    Foo myFoo = give_foo(); // Coy-Constructor wird getriggert, unmöglich bei Pointer-Rückgabe.
    

    Sehe ich als konstruiert an, da man hier ja absichtlich ein neues Objekt anlegt (Zuweisung zu einer Variable eines Typs, nicht einer Referenz). Das kann durchaus beabsichtigt sein. Wenn man keine Kopien will, kann man die Klasse entsprechend designen.

    Ich mag im Gegenzug z.B. Zeigerrückgaben nicht sonderlich, da man nicht sieht, wer für den Speicher verantwortlich ist.



  • asc schrieb:

    Ich mag im Gegenzug z.B. Zeigerrückgaben nicht sonderlich, da man nicht sieht, wer für den Speicher verantwortlich ist.

    Es sei denn, man (oder die benutzte Bibliothek) folgt konsequent der Linie, dass rohe Zeiger nicht besitzend sind.


Anmelden zum Antworten