Verwendung unterschiedlicher Parameteruebergabearten
-
hustbaer schrieb:
Das const in
void foo(const Flugzeug f);ist nämlich vollkommen für nix, du kannst diese Funktion ohne weiteres als
void foo(Flugzeug f) { f.mutator(); }implementieren, sagt kein Compiler und kein Standard was dagegen.
Ehm, aber dein zweites foo sagt dem Benutzer von foo nicht, das f nicht modifiziert wird! Und das ist nicht gut! Ich will wissen, ob f geändert wird, auch wenn es eine Kopie ist! Warum? Darum:
class Flugzeug { private: Flughafen *fh; public: Flughafen* getFH(); }; void foo(Flugzeug f) { f.getFH()->setName("Frankfurt"); // keine Änderung direkt an f, aber ich mache eine Änderung! }So, der Flughafen bleibt bei einer Kopie der gleiche.
Und foo könnte daran was rummachen. Also, wie von mir gesagt, das const ist IMMER wichtig. Das was du machst, ist wischi-waschi-Arbeit, da du const als Parameter-Modifier für unwichtig erklärst. Aber const ist immer angebracht, wenn sobald ich ein Objekt nicht ändern will.
-
Hallo Artchi,
bei folgendem Code ändert die Funktion foo trotzdem intern Werte, auch wenn der Parameter als const deklariert ist (weil ich getFH als const deklariert habe, da die Methode selbst keine Änderungen am Objekt vornimmt):
class Flughafen { public: void setName(const char *c); }; class Flugzeug { private: Flughafen *fh; public: Flughafen* getFH() const; }; void foo(const Flugzeug f) { f.getFH()->setName("Frankfurt"); // keine Änderung direkt an f, aber ich mache eine Änderung! }Ich persönlich halte nichts von "const Type" bei Funktionsparametern, da ja sowieso eine Kopie übergeben wird und es dem Aufrufer ziemlich egal sein kann, ob der Parameter verändert wird oder nicht (z.B. bei einer Längenangabe und dann wird dieser Wert intern als Zähler benutzt, anstatt ein lokale temp. Variable anzulegen).
Bei Call-By-Ref und Call-By-Pointer ist der Parameter "const" natürlich entscheidend und sehr wichtig!
-
schue schrieb:
Das, worauf er zeigt, aka die Adresse die er hat, ist der Pointee.
Ok, by-Value Uebergabe des Zeigers, das ist mir schon klar, aber ausgehend vom "Inhalt des Pointers" (s.u.)? Irgendwie bleibt es ein Zwischending ausgehend vom Standpunkt des Betrachters - rein systematisch: Pass-by-Value eines Zeigers, mehr praktisch gesehn und von einem Pointee betrachtet, irgendwass anderes, also am besten gleich: Pass-by-Pointer (das gefaellt mir am besten).
Also ich geb zu, da etwas eine eigene Namensgebung entwickelt zu haben, was ich mir gerade wieder abgewoehnen will. Bei einem Zeiger hab ich "Adresse des Zeigers", "Adresse auf die der Zeiger zeigt" und den "Inhalt der Adresse auf die der Zeiger zeigt" - welches ist der Pointee? Der Inhalt oder die Adresse auf d.d.Zg.zgt.?

-
Fabeltier schrieb:
schue schrieb:
Das, worauf er zeigt, aka die Adresse die er hat, ist der Pointee.
Ok, by-Value Uebergabe des Zeigers, das ist mir schon klar, aber ausgehend vom "Inhalt des Pointers" (s.u.)? Irgendwie bleibt es ein Zwischending ausgehend vom Standpunkt des Betrachters - rein systematisch: Pass-by-Value eines Zeigers, mehr praktisch gesehn und von einem Pointee betrachtet, irgendwass anderes, also am besten gleich: Pass-by-Pointer (das gefaellt mir am besten).
Das dürfte auch die gängigste Bezeichnung sein (außer bei C-Entwicklern, die keine C++ Referenzen kennen und deshalb func(T*) als pass-by-Reference bezeichnen).
Also ich geb zu, da etwas eine eigene Namensgebung entwickelt zu haben, was ich mir gerade wieder abgewoehnen will. Bei einem Zeiger hab ich "Adresse des Zeigers", "Adresse auf die der Zeiger zeigt" und den "Inhalt der Adresse auf die der Zeiger zeigt" - welches ist der Pointee? Der Inhalt oder die Adresse auf d.d.Zg.zgt.?

Pointer = Zeiger, Pointee = verzeigertes Objekt (also "Inhalt der Adresse, auf die der Zeiger zeigt").
Und was du als "Adresse des Zeigers" bezeichnest, ergibt letztendlich einen Doppelzeiger.
-
CStoll schrieb:
Und was du als "Adresse des Zeigers" bezeichnest, ergibt letztendlich einen Doppelzeiger.
Genau das meinte ich - bisher nannte ich es auch "Pointer-Pointer"..
-
Artchi schrieb:
hustbaer schrieb:
Das const in
void foo(const Flugzeug f);ist nämlich vollkommen für nix, du kannst diese Funktion ohne weiteres als
void foo(Flugzeug f) { f.mutator(); }implementieren, sagt kein Compiler und kein Standard was dagegen.
Ehm, aber dein zweites foo sagt dem Benutzer von foo nicht, das f nicht modifiziert wird! Und das ist nicht gut! Ich will wissen, ob f geändert wird, auch wenn es eine Kopie ist! Warum? Darum:
class Flugzeug { private: Flughafen *fh; public: Flughafen* getFH(); }; void foo(Flugzeug f) { f.getFH()->setName("Frankfurt"); // keine Änderung direkt an f, aber ich mache eine Änderung! }So, der Flughafen bleibt bei einer Kopie der gleiche.
Und foo könnte daran was rummachen. Also, wie von mir gesagt, das const ist IMMER wichtig. Das was du machst, ist wischi-waschi-Arbeit, da du const als Parameter-Modifier für unwichtig erklärst. Aber const ist immer angebracht, wenn sobald ich ein Objekt nicht ändern will.Du verstehst da was nicht. Wenn ich heute noch Zeit habe poste in ein kleines Demoprogramm. Der Punkt ist der, das "const" bei "by-value" Parametern ist vollkommen für NIX, das sagt dem Benutzer nichts. Dort wo die Funktion implementiert wird braucht kein const mehr stehen, und selbst wenn, dann mache ich mir eben nochmal eine Kopie die dann nicht const ist, und greife auf die dann non-const zu.
-
Hast Recht. Seh ich jetzt auch.
-
Nur um das für den interessierten Laien nochmal zu ergänzen - selbst bei einer Übergabe per const-Reference kann ich mir eine lokale non-const-Kopie machen. Wenn ich darüber dann aber ein Objekt manipulieren kann, auf das auch ein Member der const-Reference zeigt, ist das entweder Absicht oder die Kopiersemantik ist falsch

-
Wenn man das ganze mal aus klassischer Ansicht betrachtet, da gibt es im Wesentlichen zwei Arten der Parameterübergabe: Pass by value (Änderungen am parameter sind außen nicht sichtbar), pass by reference (Änderungen sind außen sichtbar). Der Vorteil dieser beiden Definitionen ist, daß man sie auf nahezu jede Programmiersprache anwenden kann.
In dieser Nomenklatur kann man schon sagen, dass Übergabe per Pointer ein pass by reference ist. Wer's besonders genau sagen möchte könnte auch sagen, daß man damit pass by reference implementiert. Daß da in Wirklichkeit ein Pointer by value übergeben wird spielt für die Einordnung keine Rolle. Das ist bei einer echten referenz schließlich auch nicht anders.
Allein das Verhältnis er Suchergebnisse von "pass by reference" und "pass by pointer" bei googlefight zeigt, dass "pass by pointer" kein wirklich gängiger Begriff ist.
-
Nochmal zu dem const - ich experimentiere gerade auch damit rum und werde demnaechst sicherlich noch mind. einen laengeren "Grundsatzdialog" diesbezueglich vom Zaun brechen. Hier gings mir v.a. um das genannte Thema (sh. Ueberschrift), was fuer mich nun klar gewoerden ist.
@ Jester:
Vom Verstaendnis her wuerde ich es auch genau so sehen, aber wie man hier schon lesen kann, ist "by-Pointer" schon auch ein Punkt den man durchdiskutieren kann. Das genannte Verhalten ist jedenfalls so implementierbar - sodass exakte Definition eines Begriffes und "das was man damit meint" zwar immer zwei paar Stiefel sind, die sich letztendlich wohl aber auch nicht selbst zum Thema machen sollten, solange man versteht wovon man spricht.