[linux-l] Objektübergabe durch Referenz (was: Designfrage bzgl. Deckverwaltung)

Steffen Dettmer steffen at dett.de
Fr Nov 25 23:08:43 CET 2005


* Axel Weiß wrote on Fri, Nov 25, 2005 at 20:41 +0100:
> Frank Reker schrieb:
> > retval = myfunc (&var);
> > hierbei ist klar, dass ich eine referenz uebergebe, und var nachher
> > einen anderen wert haben kann als vorher. bei:
> 
> Bei der nicht-const-Übergabe[tm] von Referenzen ist besondere Vorsicht 
> geboten. Beispiel:
> 
> class A{...};
> 
> class B{
> public:
> 	B(const A&)...
> };
> 
> void f(B &b)...
> 
> f(.) möchte den Zustand des B-Objekts ändern. Weil B aber einen 
> Konstruktor hat, der eine A-Objektreferenz akzeptiert, ist folgendes 
> möglich:
> 
> A a;
> f(a);

Ja, gemein.

> Welchen Zustand hat a jetzt? Garantiert den selben wie vor dem Aufruf von 
> f (was von f nicht beabsichtigt war). Bestenfalls bekommt man noch eine 
> Warnung zur Übersetzungszeit, die einen darauf hinweist, dass hier ein 
> temporäres Objekt erzeugt wird.

g++ macht zum Glück eine.

> Bei größeren Projekten übergebe ich Referenzen nur const - im 
> Zweifelsfall wird dabei ein temporäres read-only Objekt erzeugt (via 
> automatischer Typkonversion), das keinen Schaden anrichten kann. Wenn 
> ich mich darauf verlassen will, dass eine Funktion/Methode ein 
> *lebendes* Objekt manipuliert, übergebe ich viel lieber Zeiger. Damit 
> hat man obiges Problem nämlich nicht.

Es sei denn, es gibt einen Operator dafür...

Irgendwie wirkt das Beispiel ein bisschen künstlich, wenn man den Preis
"keine Referenzen" dafür sieht. Zeiger können ja NULL werden, find ich
doof; IMHO sollte man schreiben, was man meint, und wenn man genau ein
Objekt referenziert, kann man oft ne Referenz nehmen. Hat man optional
ein (null oder ein), ist ein Zeiger sicherlich besser, wenn man das
syntaktisch nicht verstecken kann. Na wie auch immer.

OK, ich weiss ja nicht, was A und B machen und sind; ich würde eine
non-const Ref erwarten und denken dass B A benutzt; was B aber so macht,
ist so ganz klar nicht.

Vermutlich wollte der Autor den Constructor nur für explizite
Konstruktionen verwenden und hat "explicit" vergessen.

Zuviele Konstruktoren und konvertierungsoperatoren sind ja nicht
unbedingt günstig.

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.



Mehr Informationen über die Mailingliste linux-l