Zeiger vs. Referenzen



  • Wieso? schrieb:

    hat C++ übergaupt Zeiger und Referenzen? Würde eines nicht genügen?

    Weil es praktisch ist und damit eigene Objekte natürlicher wirken.



  • Wieso? schrieb:

    hat C++ übergaupt Zeiger und Referenzen?

    Ja, hat es.

    (kleiner Tip: Nutzernamen und Beitrags-Titel werden oft überlesen - also pack deine Fragen lieber direkt (und vollständig) in den Beitrag ;))

    Würde eines nicht genügen?

    Wie man aus C weiß, würden Zeiger alleine durchaus ausreichen. Aber Referenzen bieten teilweise Vereinfachungen (kein Dereferenzieren notwendig) und erweiterte Zusicherungen gegenüber Zeigern (eine Referenz verweist IMMER auf ein Objekt - und zwar während ihrer gesamten Lebenszeit auf das selbe).



  • Wieso? schrieb:

    Würde eines nicht genügen?

    ... wofür genügen ?

    "Warum überhaupt int und double ? Würde nicht eines genügen ?"...

    Gruß,

    Simon2.



  • > Wie man aus C weiß, würden Zeiger alleine durchaus ausreichen. Aber Referenzen
    > bieten teilweise Vereinfachungen (kein Dereferenzieren notwendig) und erweiterte
    > Zusicherungen gegenüber Zeigern (eine Referenz verweist IMMER auf ein Objekt -
    > und zwar während ihrer gesamten Lebenszeit auf das selbe).

    Also sind Referenzen besser und man könnte auf Zeiger völlig verzichten.

    Simon2 schrieb:

    "Warum überhaupt int und double ? Würde nicht eines genügen ?"...

    Gute Frage. Ich würde sie eher mit float und double stellen. Wieso float, wenn es doch double gibt?



  • Hmmm... schrieb:

    Also sind Referenzen besser und man könnte auf Zeiger völlig verzichten.

    Nein. Lies den Abschnitt über die Zusicherungen nochmal (Hinweis: manchmal möchte man etwas bestimmtes garnicht zugesichert bekommen).



  • LordJaxom schrieb:

    Hmmm... schrieb:

    Also sind Referenzen besser und man könnte auf Zeiger völlig verzichten.

    Nein. Lies den Abschnitt über die Zusicherungen nochmal (Hinweis: manchmal möchte man etwas bestimmtes garnicht zugesichert bekommen).

    Welchen Abschnitt über Zusicherungen? Was meinst du damit?



  • Hmmm... schrieb:

    Welchen Abschnitt über Zusicherungen? Was meinst du damit?

    > [...] und erweiterte
    > Zusicherungen gegenüber Zeigern (eine Referenz verweist IMMER auf ein Objekt -
    > und zwar während ihrer gesamten Lebenszeit auf das selbe).

    Angenommen, Zeiger wären in C++ nicht mehr vorhanden. Was machst Du jetzt, wenn Du einen Verweis brauchst, der auch mal auf kein Objekt zeigen oder sein Ziel ändern kann? Sprich, von dem Du garnicht möchtest, dass er IMMER auf dasselbe Objekt verweist?



  • LordJaxom schrieb:

    Angenommen, Zeiger wären in C++ nicht mehr vorhanden. Was machst Du jetzt, wenn Du einen Verweis brauchst, der auch mal auf kein Objekt zeigen oder sein Ziel ändern kann? Sprich, von dem Du garnicht möchtest, dass er IMMER auf dasselbe Objekt verweist?

    Wieso sollte ich einen Verweis auf "kein Objekt" brauchen? Wozu nützt mir solch ein Verweis?
    Und ich kann doch eine Funktion, die eine Referenz erwartet, von verschiedenen Stellen aufrufen und habe somit verschiedene Ziele.
    Hast du vielleicht einen Beispiel, bei dem man Zeiger benutzen muß, ohne daß man das selbe auch mit Referenzen erreichen kann?



  • Ein paar Möglichkeiten:

    • optionale Werte - du übergibst NULL für "der Wert interessiert mich nicht"
    • Sondermarkierungen, z.B. für das Ende einer verketteten Liste
    • wo wir gerade bei Listen sind: Die Nachfolger-Beziehungen zwischen Elementen können/müssen sich während der Laufzeit auch ändern
    • ...

    (außerdem gibt es zwar Zeiger-Arithmetik (Pointer-Addition, Index-Operator etc), aber keine dazu analoge Referenz-Arithmetik)



  • CStoll schrieb:

    optionale Werte - du übergibst NULL für "der Wert interessiert mich nicht"

    Man könnte doch eine Referenz auf einen Wert "interessiert mich nicht" übergeben.

    CStoll schrieb:

    Sondermarkierungen, z.B. für das Ende einer verketteten Liste
    wo wir gerade bei Listen sind: Die Nachfolger-Beziehungen zwischen Elementen können/müssen sich während der Laufzeit auch ändern

    Verkettete Listen sind IMHO auch ohne Zeiger möglich.

    Ich glaube langsam, Zeiger existieren nur in C++ aus kompatibilitätsgründen zu C.



  • Hast du vielleicht einen Beispiel, bei dem man Zeiger benutzen muß, ohne daß man das selbe auch mit Referenzen erreichen kann?

    Ja, klar, greif mal auf ein Array zu.
    (Egal wie du das machst werden immer Zeiger im Spiel sein, auch wenn man im Code keine "sieht")



  • Hmmm... schrieb:

    Verkettete Listen sind IMHO auch ohne Zeiger möglich.

    Das möchte ich gerne sehen 😉



  • Hmmm... schrieb:

    Verkettete Listen sind IMHO auch ohne Zeiger möglich.

    Das wird sicher einige hier interessieren, wie du eine Verkettete Liste (am Betsen eine double linked list) in C++ ohne Zeiger implementieren willst. Hast du dazu ein Beispiel oder einen Link auf Lager?



  • Hmmm... schrieb:

    CStoll schrieb:

    optionale Werte - du übergibst NULL für "der Wert interessiert mich nicht"

    Man könnte doch eine Referenz auf einen Wert "interessiert mich nicht" übergeben.

    Und wie soll der Wert aussehen? Hinter einer Referenz steht IMMER eine existierende Variable, ein Zeiger kann auf NULL verweisen.

    CStoll schrieb:

    Sondermarkierungen, z.B. für das Ende einer verketteten Liste
    wo wir gerade bei Listen sind: Die Nachfolger-Beziehungen zwischen Elementen können/müssen sich während der Laufzeit auch ändern

    Verkettete Listen sind IMHO auch ohne Zeiger möglich.

    Dann zeig doch mal, wie du DAS anstellen willst.


  • Mod

    Wenn man brutal genug vorgeht, kann man auch Zeiger mit Referenzen implementieren (keine NULL-Pointer in diesem Fall, aber die braucht man nicht unbedingt), ohne Arithmetik, aber die braucht man ja nicht für verkette Listen:

    template<typename T>
    class RefPointer
    {
    public:
        RefPointer(T& x) x_(x) {}
        RefPointer& operator=(const RefPointer& other)
        {
            RefPointer tmp(other);
            (*this).~RefPointer();
            new(this) RefPointer(tmp);  // ok, hier ist ein Pointer beteiligt...
            return *this;
        }
        T& operator*() const { return x_; }
        operator RefPointer<const T>() const
        {
            return RefPointer<const T>(x_);
        }
    private:
        T& x_;
    };
    

    Alles eine Frage der kriminellen Energie, die man aufbringt 🙂 - dass new einen Pointer zurückgibt, kann man so nat. nicht ändern.



  • pumuckl schrieb:

    Hmmm... schrieb:

    Verkettete Listen sind IMHO auch ohne Zeiger möglich.

    Das wird sicher einige hier interessieren, wie du eine Verkettete Liste (am Betsen eine double linked list) in C++ ohne Zeiger implementieren willst. Hast du dazu ein Beispiel oder einen Link auf Lager?

    Ich habe kein Beispiel, aber denkbar wären zwei Ansätze:
    1. Alle Listenelemente befinden sich bereits in einem großen Array, so daß die Links einfach Indezes in dieses Array sind.
    2. Statt Zeigern werden Referenzen verwendet.



  • Hmmm... schrieb:

    Ich habe kein Beispiel, aber denkbar wären zwei Ansätze:
    1. Alle Listenelemente befinden sich bereits in einem großen Array, so daß die Links einfach Indezes in dieses Array sind.
    2. Statt Zeigern werden Referenzen verwendet.

    Dann hast Du jetzt zwei Möglichkeiten:
    1. Glaube uns, dass beide Ansätze in eine Sackgasse führen werden.
    2. Implementiere eine solche Liste und komme selbst an den Punkt wo Du mit Referenzen nicht weiterkommst.

    (Ansatz 1 würde jedenfalls schonmal die Flexibilität einer solchen Liste zerstören, da der Array eine feste Länge haben müsste)



  • CStoll schrieb:

    Hmmm... schrieb:

    CStoll schrieb:

    optionale Werte - du übergibst NULL für "der Wert interessiert mich nicht"

    Man könnte doch eine Referenz auf einen Wert "interessiert mich nicht" übergeben.

    Und wie soll der Wert aussehen? Hinter einer Referenz steht IMMER eine existierende Variable, ein Zeiger kann auf NULL verweisen.

    CStoll schrieb:

    Sondermarkierungen, z.B. für das Ende einer verketteten Liste
    wo wir gerade bei Listen sind: Die Nachfolger-Beziehungen zwischen Elementen können/müssen sich während der Laufzeit auch ändern

    Verkettete Listen sind IMHO auch ohne Zeiger möglich.

    Dann zeig doch mal, wie du DAS anstellen willst.

    ich weiss nicht wie er es anstellen würde aber ich würde es mit einer referenz auf einem dummy wert machen.
    wer sagt das das ende einer liste mit NULL definiert sein muss ?
    aber ich tendiere auch zu deiner art der anwendung.

    ich verwende referenzen eigentlich so:
    alles was pointertype(auch arrays) ist, wird als pointer weitergegeben (da pointer auch NULL sein können)
    alles was am stack liegt(ausnahme primitive datentypen), bzw "garantiert" existiert und nie NULL sein kann, wird als referenz übergeben.



  • Hmmm... schrieb:

    1. Alle Listenelemente befinden sich bereits in einem großen Array, so daß die Links einfach Indezes in dieses Array sind.

    Was meinst du, was der Prozessor aus einem Zeiger macht? Einen Index auf ein sehr großes Array (genannt "Speicher") 😉

    2. Statt Zeigern werden Referenzen verwendet.

    Kannst du machen - aber damit kann die Liste nur sehr eingeschränkt verwendet werden (eine Referenz lässt sich nach ihrer Erzeugung nicht mehr mit regulären Mitteln umbiegen - solche Brachiallösungen, wie sie camper präsentiert hat, sind extrem grenzwertig (wenn nicht sogar undefiniert)).



  • LordJaxom schrieb:

    2. Implementiere eine solche Liste und komme selbst an den Punkt wo Du mit Referenzen nicht weiterkommst.

    Das Problem bei einer Heap-basierten Liste wird sein, daß new und delete mit Zeigern arbeiten. Wenn man aber Funktionen bereitstellt wie etwa:

    ListElement& newListElement()
    {
        return * new ListElement;
    }
    
    void deleteListElement (ListElement &l)
    {
        delete &l;
    }
    

    Dann könnte man bestimmt eine beliebige Listen-Implementation nehmen und sie auf Referenzen umstellen.


Anmelden zum Antworten