Wann ein Zeiger als Parameter wann eine Referenz?
-
Ponto schrieb:
Jemand, der das Programm wartet oder erweitert, wird bei Referenzen sicherstellen, dass gültige Objekte übergeben werden. Bei Zeigern wird er aber annehmen, dass 0 übergeben werden kann.
eben nicht.
beivoid eingabeStudent(Student* stud);
würdest du da erwarten, daß man nen nullzeiger übergeben darf? irgendwie kann ich mich gerade an gar keine funktion erinnern, die nen nullzeiger essen mag (außer dem operator delete, aber dafür bin ich nicht verantwortlich zu machen!).
-
otze schrieb:
eine frage hab ich aber:
dürfen funktionen, die einen pointer als parameter erwarten die aufgabe des "auf 0 testen" auf den rest des programms auslagern? oder soll in den fällen, wo der funktion kein nullpointer übergeben werden darf,immer innerhalb der funktion getestet werden?Erstens) Wieso überhaupt einen Zeiger und keine Referenz? Darum geht doch der ganze Thread hier und ich habe im zweiten Post schon gesagt, dass man eigentlich nie Zeiger zu Übergabe braucht. Habe aber ehrlich gesagt nicht wirlich verstanden, ob Volkard mir da jetzt wiedersprochen oder zugestimmt hat
Zweitens) Wenn eine Funktion einen Zeiger erwartet der nicht null sein darf, muss da _keine_ Abfrage rein. Du schreibst ja selbst, dass man nur prüfen muss wenn man sich nicht sicher sein kann. Die Funktion kann aber nicht wissen, ob ich mir sicher bin oder nicht. Man könnte höchsten ein Assert einbauen um eventuelle "Flüchtigkeits"-Fehler zu vermeiden.
// ach mist, nun war er schon wieder schneller als ich
-
DrGreenthumb schrieb:
Erstens) Wieso überhaupt einen Zeiger und keine Referenz? Darum geht doch der ganze Thread hier und ich habe im zweiten Post schon gesagt, dass man eigentlich nie Zeiger zu Übergabe braucht. Habe aber ehrlich gesagt nicht wirlich verstanden, ob Volkard mir da jetzt wiedersprochen oder zugestimmt hat
da widerspreche ich energisch (wobei ich aber manchmal das gegenteil von dem schreibe, was ich meine), weil mich nicht die implementierung der funktion interessiert. die mache ich einmal und gut ists.
mich interessiert die imlementierung des aufrufers.
ob ich dacout<<a<<endl;//ok, a ist korrekt f(a,b,c); g(a,b); h(b,c); i(a,b,c); cout<<a<<endl;//ups, a ist kaput gegangen, wieso nur???
oder
cout<<a<<endl;//ok, a ist korrekt f(a,b,c); g(&a,b); h(b,c); i(a,b,c); cout<<a<<endl;//ups, a ist kaput gegangen, es lag offensichtlich an g
stehen habe.
die fehlersuchzeit beim aufrufenden code sinkt, wenn man konsequent zeiger für non-const-objekte und const-referenzen oder kopien für const-objekte benutzt.
-
volkard schrieb:
mich interessiert die imlementierung des aufrufers.
...
die fehlersuchzeit beim aufrufenden code sinkt, wenn man konsequent zeiger für non-const-objekte und const-referenzen oder kopien für const-objekte benutzt.Der Meinung war ich auch immer, bis ich mich dann doch von der einfacheren Syntax hab überzeugen lassen. Und in der Praxis fahre ich damit gut. Solche Debug-Situationen sind nach meiner Erfahrung nicht wirklich realistisch. Normalerweise haben die Funktionen dann ja doch sprechendere Namen und man sieht anhand des Kontextes auf Anhieb, wer da irgendwo was verändern möchte und wer nicht.
Jedenfalls sollte man das.
-
volkard schrieb:
void eingabeStudent(Student* stud);
würdest du da erwarten, daß man nen nullzeiger übergeben darf? irgendwie kann ich mich gerade an gar keine funktion erinnern, die nen nullzeiger essen mag (außer dem operator delete, aber dafür bin ich nicht verantwortlich zu machen!).
Das kommt auf den Kontext an. Wenn ich jedoch auf keinen Fall einen 0 Zeiger haben will, nehme ich eine Referenz und fertig. Da bleibt nicht viel Interpretationsspielraum.
-
volkard schrieb:
warum verwende ich std::swap? aus historischen gründen. das ding hat sich in dieser form fest eingebürgert, bevor man erkannte, wie falsch es eigentlich ist.
Was ist denn am std::swap falsch und wer hat erkannt, wie falsch dies eigentlich ist?
-
DrGreenthumb schrieb:
Der Meinung war ich auch immer, bis ich mich dann doch von der einfacheren Syntax hab überzeugen lassen.
also ist der grund die einfacher syntax? nicht daß man echt zwischen null-sein-könnern und echten objekten unerscheidet, um irgendwelche sicherheut oder dokumentation dazuzugewinnen? das argument konnte ich nämlich nie nachvollziehen.
einfachere schreibe ist natürlich ein argument. und daß man, wenn man sich sagt: ich will so oft we möglich refs benutzen, dann einfach nach null oder nicht-null trennen muß, ich auch klar. da null-sein-könner echt selten vorkommt, solltest du kaum noch zeiger benutzen. als übergabeparameter fast nie. gerademal innerhalb von dynamischen datenstrukturen für private hilfsfunktionen. als attribute auch nur bei manchen verkettungen. jeder mitarbeiter hat sicher nen chef, also dort kein zegier zum chef, sondern ne ref.Und in der Praxis fahre ich damit gut. Solche Debug-Situationen sind nach meiner Erfahrung nicht wirklich realistisch. Normalerweise haben die Funktionen dann ja doch sprechendere Namen und man sieht anhand des Kontextes auf Anhieb, wer da irgendwo was verändern möchte und wer nicht.
Jedenfalls sollte man das.stimmt. mir scheinen sie auch selten. eigentlich nur in code, den ich nicht schreiben würde.
beide argumente sind schwach. geradezu windig. auf sand gebaut. irrelevant.
mir geistert eher irgendwas tieferes im sinne. irgendwie *sind* zeiger dinge, die auf was anderes zeigen, während refs irgendwie bloß vrtuelle namen sind. mein chef-attribut ist für mch ein realer zeiger auf ne andere person. den zeiger kann ich als verkettngspfeilchen in allen meinen diagrammen sehen. dieses verkettngspfeilchen hat substanz. es *ist* der zeiger. zeiger sind verkettngspfeilchen und verkettngspfeilchen sind zeiger. also da würde ich mir endlos schwer tun, aus referenzen umzustellen.
bei lokalen variablen benutze ich gerne refs als alias.
also funktionsparameter mag ich es, auszudrücken, ob was const oder non-const ist. mir machts's den code irgendwie klarer. auch innerhalb fasse ich den zeiger ja mit * an, udn dann sehe ich gleich: aha, das ist jetzt passiert ein seiteneffekt. nix bloß lokles. kann mir schwer vorstellen, wie es wäre, wenn ich ganz darauf verzichten würde. kann sein, daß es mir hete ar nicht mehr weh tun würde, weil meine funktionen nzwischen recht klein sind und meist recht gute naen tragen. schweirige sache das. aber an den normalen funktionen es zu messen ist eh nicht gut. an den schlimmen muß man messen. und die nächste zeit habe ich gar nicht vor, was schwieriges zu schreiben.
-
Ponto schrieb:
Was ist denn am std::swap falsch und wer hat erkannt, wie falsch dies eigentlich ist?
es sollte nicht als
swap(a,b);
sondern als
swap(&a,&b);
augerufen werden.
ich hab's erkannt.
-
volkard schrieb:
...
sondern alsswap(&a,&b);
...
Das ist aber höchst mißverständlich. Was wird hier vertauscht? a und b? Die Adressen von a und b? Zeiger auf a und b? Die Speicherbereiche, wo a und b liegen?
Das ursprüngliche swap sagt klar und deutlich, was getauscht wird.
-
volkard schrieb:
also ist der grund die einfacher syntax?
ja, für mich schon.
Ich stimm dir aber zu, was die Betrachtung eines Zeigers angeht. Wenn Klasse 1 einen Verweis zu Klasse 2 hat, speicher ich den auch als Zeiger. Selbst wenn ein Referenz möglich wäre. Nur gehe ich nicht soweit das auf jede Funktion zu übertragen. Ist vielleicht ein wenig unkonsequent.nicht daß man echt zwischen null-sein-könnern und echten objekten unerscheidet, um irgendwelche sicherheut oder dokumentation dazuzugewinnen? das argument konnte ich nämlich nie nachvollziehen.
Das wird einfach von C kommen. Dort ist das Gang und Gebe, wegen fehlender Überladungsmöglichkeiten.
-
Ponto schrieb:
Das ist aber höchst mißverständlich. Was wird hier vertauscht? a und b? Die Adressen von a und b? Zeiger auf a und b? Die Speicherbereiche, wo a und b liegen?
ist eindeutig, wenn man immer zeiger verwendet. natürlich ist es mißverständlich, wenn mal mal so und mal anders programmiert.
solhe uneindeutigkeiten hat man oft.
beivoid print(char* ch);
was wird ausgegeben? der zeiger oder der dahinterleigende string?
ist irgendwie historisch gewachsene vereinbarung, daß man normale zeiger als hexzahl ausgibt, aber zeiger auch char als dahinterliegenden string.
so ist auch gewachsen, was man mit swap meint. es hat keine weitere klarheit als allein die, daß wir uns drauf geeinigt haben.
-
@Volkard
Herrlich wie du wieder aus einer reinen Style-Sache eine Absoulte-Wahrheits-Sache machstDas Thema Reference vs. Pointer bei Funktionsparametern wird in C++ Kreisen seit bestimmt 10 Jahren heftig diskutiert. Jedesmal bringen beide Seiten gute Argumente (die Sache mit der 0, die Sache mit Fortran, die Sache mit Information Hiding, die Sache mit den Pointer-to-const und viele Sachen mehr...) und jedesmal bleibt das Ergebnis: Just a matter of style.
-> Sei konsistent. Passe dich an deine Umgebung an.Du trommelst natürlich sehr laut und das führt, zumindest bei mir, schnell dazu, dass man deshalb meint, du hättest die Richtige-Lösung(TM) parat.
Ich möchte zum Ausgleich nur auf comp.lang.c++.moderated hinweisen.
Eine Suche nach "reference vs pointer" bringt einem unzähligen Diskussionen. Dort findet man auch genügend Leute, die genauso laut wie Volkard trommeln, dabei aber genau in die entgegengesetzte Richtung rudern.
Nur mal so als Beispiel:Some brick-headed
old C programmers would even tell you that the pointer form is superior,
that it is more self documenting because the passing of the pointer is
visible, or some such hogwash. This is just low level thinking, and a
crutch that should be thrown away. Many programming languages use pass
by reference and have a lot less trouble with it than C beginners have
with pointers! So don't let some old fart beat you over the head with
his crutch.Ich persönlich ziehe daraus den Schluss, dass es auf beiden Seiten Heißsporne gibt die die andere Seite missionieren wollen. Wenn ich aber genauer hinschaue finde ich auf beiden Seiten gute Argumente, die man wohl am Besten immer wieder im konkreten Kontext berücksichtigt.
-
HumeSikkins schrieb:
Du trommelst natürlich sehr laut und das führt, zumindest bei mir, schnell dazu, dass man deshalb meint, du hättest die Richtige-Lösung(TM) parat.
haste meinen beitrag vom 01 Aug 2004 22:37 gelesen? dann hab ich doch eindeutig bewiesen, die einzig richtige lösung parat zu haben, oder?
-
Interessante Beweisführung. So in etwa: "Mir gefällt es besser und ich finde es leichter. QED"