Referenz oder Pointer als Member?



  • Hallo,

    ich bin im Internet über Coding Rules gestolpert, in denen es heißt, dass man immer eine Referenz einem Pointer den Vorzug geben sollte...

    Ich habe bisher immer so programmiert, dass wenn Polymorphie zum Einsatz kam, ich mit Pointern als Member Variablen in meinen Klassen gearbeitet habe. Auch so, wenn man sich Beispielcode ansieht, sehe ich irgendwie nie Referenzen als Membervariablen einer Klasse. Habe ich mir immer nur die falschen Beispiele angesehen? Oder anders: Ist es "normal" Referenzen als Membervariablen Pointern vorzuziehen?

    Vielen Dank und noch einen schönen Sonntagabend!

    Tom



  • T00m schrieb:

    ich bin im Internet über Coding Rules gestolpert, in denen es heißt, dass man immer eine Referenz einem Pointer den Vorzug geben sollte...

    Das ist totaler Schwachsinn.



  • volkard schrieb:

    T00m schrieb:

    ich bin im Internet über Coding Rules gestolpert, in denen es heißt, dass man immer eine Referenz einem Pointer den Vorzug geben sollte...

    Das ist totaler Schwachsinn.

    Genau. Diese "Regel" scheiter auch schon daran, dass es nicht immer möglich ist eine Referenz zu verwenden.
    Wenn man natürlich eine Referenz verwenden kann, dann sollte man dies tun, da man sich Dereferenzierungen spart und die es einfach komfortabler ist.



  • dfasd schrieb:

    Wenn man natürlich eine Referenz verwenden kann, dann sollte man dies tun

    Das ist totaler Schwachsinn.



  • Ok, danke euch Beiden erstmal für die schnellen Antworten.
    Ich bin aber total unsicher in der Wahl zwischen Referenzen und Pointern...
    Wann ist es denn sinnvoll eine Referenz als Membervariable zu nehmen und wann lieber einen Pointer?
    Außerdem habe ich oft das Problem, dass ich in meinem Code global Pointer habe, die ja nicht so schick sind... ist aber wohl ne Design Schwäche von mir.

    Viele Grüße
    Tom



  • dfasd schrieb:

    Wenn man natürlich eine Referenz verwenden kann, dann sollte man dies tun, da man sich Dereferenzierungen spart und die es einfach komfortabler ist.

    Das ist absolut richtig.



  • T00m schrieb:

    Ok, danke euch Beiden erstmal für die schnellen Antworten.
    Ich bin aber total unsicher in der Wahl zwischen Referenzen und Pointern...

    Zum Glück ist es oft egal, was Du nimmst. Der Code wird von Pointern nicht schlechter. Da sich Referenzen wie echte Objekte anfühlen, ist es oft verwirrend, Sachen wie

    Foo::f(){
       x+=5;
       bar.update(2);
    }
    

    zu lesen. Viele denken hier, bar sei ein Objekt, das ganz und gar Teil von *this ist.
    Wenn bar außerhalb lebt, kann man das mit

    Foo::f(){
       x+=5;
       bar->update(2);
    }
    

    ruhig herausbrüllen.
    Referenzen hier sehe ich eigentlich nur bei

    Foo::f(){
       x+=5;
       theWorld->update(2);
    }
    

    wenn jedes Objekt eine Referenz auf die Welt hält, in der es lebt. Oder auf die Socketbibliothek oder den Threadpool oder sowas.

    T00m schrieb:

    Außerdem habe ich oft das Problem, dass ich in meinem Code global Pointer habe, die ja nicht so schick sind... ist aber wohl ne Design Schwäche von mir.

    Die löschen sich aber dann nicht. Ich habe eigentlich nur globale Objekte. Außer sowas wie lookup-tables, da nehme ich auch mal globale Zeiger.


  • Mod

    T00m schrieb:

    Ok, danke euch Beiden erstmal für die schnellen Antworten.
    Ich bin aber total unsicher in der Wahl zwischen Referenzen und Pointern...
    Wann ist es denn sinnvoll eine Referenz als Membervariable zu nehmen und wann lieber einen Pointer?
    Außerdem habe ich oft das Problem, dass ich in meinem Code global Pointer habe, die ja nicht so schick sind... ist aber wohl ne Design Schwäche von mir.

    Referenzen können als Member genau eines: Unveränderbar auf ein einmal (beim Konstruktoraufruf) festgelegtes Objekt verweisen. Hat man diese Anforderung, so ist die Referenz die richtige Wahl.

    Pointer können andere Sachen: Auf andere Objekte zeigen, auf Speicherbereiche zeigen, auf Null zeigen, ihren Wert ändern, Polymorphie ermöglichen. Hat man diese Anforderungen, ist es richtig, einen Pointer zu verwenden.



  • Ich habe schon einige Male gelesen, dass Mehrfachreferenzen undefiniertes Verhalten hervorrufen.
    Wenn ich eine Klasse, die eine Referenz enthält, referenziere, habe ich dann bereits eine Mehrfachreferenz?

    In Code:

    #include <iostream>
    
    struct foo
    {
    	foo(int& i): val(i) { }
        int& val;
    };
    
    int main()
    {
    	int a = 5;
    	foo test(a);
    	foo& testref = test;
    	testref.val = 2;
    	std::cout << "a: " << a << " - test.val: " << test.val << " - testref.val: " << testref.val;
    	std::cin.get();
    }
    

    Ist es definiertes Verhalten, dass überall 2 herauskommt? Und wenn ja, stimmt das mit den Mehrfachreferenzen oder habe ich das falsch in Erinnerung?



  • SeppJ schrieb:

    Referenzen können als Member genau eines: Unveränderbar auf ein einmal (beim Konstruktoraufruf) festgelegtes Objekt verweisen. Hat man diese Anforderung, so ist die Referenz die richtige Wahl.

    Pointer können andere Sachen: Auf andere Objekte zeigen, auf Speicherbereiche zeigen, auf Null zeigen, ihren Wert ändern, Polymorphie ermöglichen. Hat man diese Anforderungen, ist es richtig, einen Pointer zu verwenden.

    Zusatzbemerkung: Referenzen können Polymorphie auch.



  • Nukularfüsiker schrieb:

    dfasd schrieb:

    Wenn man natürlich eine Referenz verwenden kann, dann sollte man dies tun, da man sich Dereferenzierungen spart und die es einfach komfortabler ist.

    Das ist absolut richtig.

    Also der Teil nach dem Komma ist totaler Schwachsinn.



  • hustbaer schrieb:

    Nukularfüsiker schrieb:

    dfasd schrieb:

    Wenn man natürlich eine Referenz verwenden kann, dann sollte man dies tun, da man sich Dereferenzierungen spart und die es einfach komfortabler ist.

    Das ist absolut richtig.

    Also der Teil nach dem Komma ist totale Schwachsinn.

    Da sind zwei Kommas. Mit der pauschalen Antwort wollte ich auf volkards Weise "argumentieren", aber totaler Schwachsinn ist die Aussage doch nicht. Im Sinne von: Wenn man eine Referenz braucht, sollte man auch eine benutzen, statt sich den Code mit Sternchen vollzukleistern.
    Pauschalisierungen sind halt generell immer schlecht.



  • Nukularfüsiker schrieb:

    Wenn man eine Referenz braucht, sollte man auch eine benutzen

    Ja, wenn man sie braucht, aber nicht wenn man sie verwenden kann.



  • Nukularfüsiker schrieb:

    Also der Teil nach dem Komma ist totale Schwachsinn.

    Da sind zwei Kommas.

    Es ist deiner Erklärung erster Teil gemeint.
    Referenzen und Zeiger werden dereferenziert, wenn man darauf zugreift. Das wird bei beiden gleich lange dauern. Einzig ist die Verwendung von Referenzen angenehmer, da man sich bei manchen Sachen ein "*" oder eben einen "->" sparen kann.



  • Nukularfüsiker schrieb:

    hustbaer schrieb:

    Nukularfüsiker schrieb:

    dfasd schrieb:

    Wenn man natürlich eine Referenz verwenden kann, dann sollte man dies tun, da man sich Dereferenzierungen spart und die es einfach komfortabler ist.

    Das ist absolut richtig.

    Also der Teil nach dem Komma ist totale Schwachsinn.

    Da sind zwei Kommas. Mit der pauschalen Antwort wollte ich auf volkards Weise "argumentieren", aber totaler Schwachsinn ist die Aussage doch nicht. Im Sinne von: Wenn man eine Referenz braucht, sollte man auch eine benutzen, statt sich den Code mit Sternchen vollzukleistern.
    Pauschalisierungen sind halt generell immer schlecht.

    Wähle ein beliebiges der beiden Kommata aus, macht keinen Unterschied.

    Ich meine die Begrüngung "da man sich Dereferenzierungen spart und es einfach komfortabler ist" ist Schwachsinn. Ob ich -> oder . schreibe ist egal. Praktisch sind Referenzen IMO aus anderen Gründen. z.B. deswegen weil sie nicht "re-bound" werden können, oder weil sie immer auf was gültiges zeigen "müssen".

    "." statt "->" halte ich eigentlich für eher schlecht als gut, denn "p->" macht wenigstens kenntlich dass hier über einen Zeiger zugegriffen wird, also "p" nicht selbst das objekt "ist". "r." dagegen sieht genau so aus als ob "r" selbst das Objekt wäre. Wobei ich der Meinung bin dass das ein relativ schwaches Argument ist, dem man keine besondere Bedeutung zumessen sollte.


Anmelden zum Antworten