 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Klaus Schroeder Guest
|
Posted: Fri Mar 24, 2006 12:06 am Post subject: Zuweisungsoperator |
|
|
Nachdem ich jahrelang Zuweisungsoperatoren immer mit dem Datentyp const
T & definiert habe, stieß ich in einem C++-Lehrbuch auf den Hinweis,
dass ein Zuweisungsoperator mit dem Datentyp T & definiert werden
sollte, und nicht mit const T &.
Noch überraschter war ich, als ich feststellen mußte, dass das auch für
elementare Datentypen in C++ gilt, dass also folgendes Programm:
// ---- assigntest.cpp ----
# include <iostream>
using namespace std;
int main (void)
{
int x = 3,
y = 5,
z;
(z = y) = x;
cout << z << endl; // Ausgabe: 3
}
fehlerfrei läuft, während ein entsprechendes C-Programm:
// ---- assigntest.c ----
# include <stdio.h>
int main (void)
{
int x = 3,
y = 5,
z;
// (z = y) = x; !!! Funktioniert nicht in C !!!
printf ("%d\n", z);
return 0;
}
wie erwartet, die Fehlermeldung ausgibt: (z = y) ist kein L-Wert!
Kann mir jemand erklären, was die Entwickler von C++ veranlaßt hat,
diese Änderung gegenüber C vorzunehmen, bzw. warum man einen solchen
Blödsinn wie (z = y) = x; unbedingt machen können soll?
Gruß Klaus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Daniel Albuschat Guest
|
Posted: Fri Mar 24, 2006 8:06 am Post subject: Re: Zuweisungsoperator |
|
|
Hallo Klaus,
Klaus Schroeder wrote:
| Quote: | Nachdem ich jahrelang Zuweisungsoperatoren immer mit dem Datentyp
const T & definiert habe [...]
|
Dem "Datentyp"? Dem Datentyp des Parameters oder des Rueckgabewerts?
Ich nehme mal an Rueckgabe, aber als ich es das erste Mal gelesen habe,
las ich es als Parametertyp und war dementsprechend Verwirrt beim
Rest des Postings. :)
[a = b ist in C++ ein L-Wert, in C nicht]
| Quote: | Kann mir jemand erklären, was die Entwickler von C++ veranlaßt hat,
diese Änderung gegenüber C vorzunehmen, bzw. warum man einen solchen
Blödsinn wie (z = y) = x; unbedingt machen können soll?
|
Naja, das kann z.B. in expression templates sinnvoll sein. In C hat es
in der Tat keinen Sinn gemacht, weil da = ein definiertes Verhalten fuer
alle Operanden hatte, welche die erste Zuweisung semantisch zu einem
no-op machen wuerde -- in C++ kann man das Verhalten jedoch beliebig
abaendern und damit kann (z = y) = x; etwas ganz anderes sein als
z = x;.
MfG,
Daniel
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Markus Moll Guest
|
Posted: Fri Mar 24, 2006 12:06 pm Post subject: Re: Zuweisungsoperator |
|
|
Hallo
Daniel Albuschat wrote:
| Quote: | Klaus Schroeder wrote:
[a = b ist in C++ ein L-Wert, in C nicht]
Kann mir jemand erklären, was die Entwickler von C++ veranlaßt hat,
diese Änderung gegenüber C vorzunehmen, bzw. warum man einen solchen
Blödsinn wie (z = y) = x; unbedingt machen können soll?
Naja, das kann z.B. in expression templates sinnvoll sein. In C hat es
in der Tat keinen Sinn gemacht, weil da = ein definiertes Verhalten fuer
alle Operanden hatte, welche die erste Zuweisung semantisch zu einem
no-op machen wuerde -- in C++ kann man das Verhalten jedoch beliebig
abaendern und damit kann (z = y) = x; etwas ganz anderes sein als
z = x;.
|
Und um noch ein prominentes Beispiel hinterher zu schieben, damit man sieht,
daß das alles nicht nur Unfug ist, den man nicht machen sollte:
std::auto_ptr.
Gruß
Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Mar 24, 2006 1:06 pm Post subject: Re: Zuweisungsoperator |
|
|
Klaus Schroeder wrote:
| Quote: | Nachdem ich jahrelang Zuweisungsoperatoren immer mit dem
Datentyp const T & definiert habe, stieß ich in einem
C++-Lehrbuch auf den Hinweis, dass ein Zuweisungsoperator mit
dem Datentyp T & definiert werden sollte, und nicht mit const
T &.
|
Es geht um den Typ der Rückgabe, vermute ich. Die Funktion selbe
darf nur in seltenen Fällen (Proxy, z.B.) const, und der
Parameter soll meist (aber nicht immer) const. Beim Rückgabetyp
geht es ehe um Konvention, und beide const und nicht const
funktionnieren in den meisten Fällen. Wie du festgestellt hast,
emuliert nicht const am nähesten das Verhalten bei den
eingebauten Typen in C++.
| Quote: | Noch überraschter war ich, als ich feststellen mußte, dass das
auch für elementare Datentypen in C++ gilt, dass also
folgendes Programm:
// ---- assigntest.cpp ----
# include <iostream
using namespace std;
int main (void)
{
int x = 3,
y = 5,
z;
(z = y) = x;
cout << z << endl; // Ausgabe: 3
}
fehlerfrei läuft,
|
Möglicherweise. Es enthält immerhin undefiniertes Verhalten,
dann z zweimal modifiziert wird, ohne dass inzwischen ein
Sequenz-Punkt auftaucht.
| Quote: | während ein entsprechendes C-Programm:
// ---- assigntest.c ----
# include <stdio.h
int main (void)
{
int x = 3,
y = 5,
z;
// (z = y) = x; !!! Funktioniert nicht in C !!!
printf ("%d\n", z);
return 0;
}
wie erwartet, die Fehlermeldung ausgibt: (z = y) ist kein
L-Wert!
|
Weil die Regel hier anders sind in C als in C++.
| Quote: | Kann mir jemand erklären, was die Entwickler von C++ veranlaßt
hat, diese Änderung gegenüber C vorzunehmen, bzw. warum man
einen solchen Blödsinn wie (z = y) = x; unbedingt machen
können soll?
|
Die allgemeine Regel in C++ ist, dass wenn der (r-Value) Wert
eines Operators dem Wert eines Objektes entspricht, dann ist das
Ergebnis einen l-Value. Ich denke, dass die Regel vor der NRVO
entstanden ist, um Sache wie :
T&
T::operator+=( T const& other )
{
return *this = *this + other ;
}
zu erlauben.
Wenn man versucht es mit eingebauten Typen zu verwenden, stosst
man fast immer auf undefiniertes Verhalten. Mit Benutzer
definierten Typen dagegen schützen die Sequenzpunkte beim
Funktionsaufruf und return gegend dem undefinierten Verhalten.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Klaus Schroeder Guest
|
Posted: Fri Mar 24, 2006 1:23 pm Post subject: Re: Zuweisungsoperator |
|
|
Daniel Albuschat schrieb:
| Quote: |
Dem "Datentyp"? Dem Datentyp des Parameters oder des Rueckgabewerts?
Ich nehme mal an Rueckgabe, aber als ich es das erste Mal gelesen habe,
las ich es als Parametertyp und war dementsprechend Verwirrt beim
Rest des Postings. :)
|
Das tut mir leid. Wenn ich sage: Eine Funktion (oder Methode) hat einen
Datentyp, dann meine ich den Datentyp des Returnwerts. Ob das eine
vernünftige Ausdrucksweise ist, darüber kann man sicherlich streiten.
| Quote: | [a = b ist in C++ ein L-Wert, in C nicht]
|
Richtig.
| Quote: | Kann mir jemand erklären, was die Entwickler von C++ veranlaßt hat,
diese Änderung gegenüber C vorzunehmen, bzw. warum man einen solchen
Blödsinn wie (z = y) = x; unbedingt machen können soll?
Naja, das kann z.B. in expression templates sinnvoll sein.
|
Das verstehe ich nicht. Kannst Du das einmal erklären oder ein Beispiel
dafür angeben?
| Quote: | In C hat es
in der Tat keinen Sinn gemacht, weil da = ein definiertes Verhalten fuer
alle Operanden hatte, welche die erste Zuweisung semantisch zu einem
no-op machen wuerde -- in C++ kann man das Verhalten jedoch beliebig
abaendern und damit kann (z = y) = x; etwas ganz anderes sein als
z = x;.
|
Auch in C++ hat = für elementare Datentypen (!) ein definiertes
Verhalten für alle Operanden und auch dort wird in dem angegebenen
Programmbeispiel (z = y) zu einem "no-op". M.a.W. der Ausdruck (z = y) =
x im Programmbeispiel ist und bleibt ein Nonsense.
Dass man bei der Überladung des Zuweisungsoperators für einen
selbstdefinierten Datentyp ein beliebiges Verhalten definieren kann,
also auch die Bewertung von (z = y) als L-Wert, wenn man es für
wünschenswert hält, ist doch eine ganz andere Sache. Das könnte man doch
auch dann machen, wenn in C++ das Verhalten des = aus C für elementare
Datentypen übernommen worden wäre.
Ich würde nach wie vor einen Zuweisungsoperator so deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich besondere
Gründe habe, den Zuweisungsausdruck zu einem L-Wert machen zu wollen.
MfG, Klaus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Klaus Schroeder Guest
|
Posted: Fri Mar 24, 2006 4:06 pm Post subject: Re: Zuweisungsoperator |
|
|
Markus Moll schrieb:
| Quote: | Hallo
Daniel Albuschat wrote:
....
Und um noch ein prominentes Beispiel hinterher zu schieben, damit man sieht,
daß das alles nicht nur Unfug ist, den man nicht machen sollte:
std::auto_ptr.
Gruß
Markus
|
Ich verstehe ja, dass bei std::auto_ptr der Zuweisungsoperator auf
keinen Fall mit einer const-Referenz bewertet werden darf, wenn man
Mehrfachzuweisungen zulassen will (was aber bei auto_ptr ziemlich
blödsinnig ist), was hat das aber damit zu tun, dass ein elementarer
int-Ausdruck (z = y) unbedingt ein L-Wert sein müsste?
Ich kann doch für den Zuweisungsoperator für std::auto_ptr definieren,
wass ich will, und von dieser Freiheit wurde doch in diesem Fall auch in
besonderer Weise Gebrauch gemacht. Das Ganze würde doch auch
funktionieren, wenn (z = y) in C++ kein L-Wert wäre!
MfG, Klaus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Markus Moll Guest
|
Posted: Fri Mar 24, 2006 5:06 pm Post subject: Re: Zuweisungsoperator |
|
|
Hallo
Rolf Magnus wrote:
| Quote: | Klaus Schroeder wrote:
Ich würde nach wie vor einen Zuweisungsoperator so deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich besondere
Gründe habe, den Zuweisungsausdruck zu einem L-Wert machen zu wollen.
Ich lasse das const links meistens weg, da ich keinen Grund sehe, so eine
Einschränkung zu machen.
|
Ich auch, aber was anderes: ist das Ergebnis nicht immer noch ein lvalue?
Sind nicht nur "Nicht-referenz"-Rückgabewerte rvalues?
Daß man nicht
MeinTyp x,y,z;
(x = y) = z;
sagen kann, liegt doch dann eher daran, daß (x=y) nicht modifiable ist...
Gruß
Markus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Fri Mar 24, 2006 5:06 pm Post subject: Re: Zuweisungsoperator |
|
|
Klaus Schroeder wrote:
| Quote: | In C hat es
in der Tat keinen Sinn gemacht, weil da = ein definiertes Verhalten fuer
alle Operanden hatte, welche die erste Zuweisung semantisch zu einem
no-op machen wuerde -- in C++ kann man das Verhalten jedoch beliebig
abaendern und damit kann (z = y) = x; etwas ganz anderes sein als
z = x;.
Auch in C++ hat = für elementare Datentypen (!) ein definiertes
Verhalten für alle Operanden und auch dort wird in dem angegebenen
Programmbeispiel (z = y) zu einem "no-op". M.a.W. der Ausdruck (z = y) =
x im Programmbeispiel ist und bleibt ein Nonsense.
Dass man bei der Überladung des Zuweisungsoperators für einen
selbstdefinierten Datentyp ein beliebiges Verhalten definieren kann,
also auch die Bewertung von (z = y) als L-Wert, wenn man es für
wünschenswert hält, ist doch eine ganz andere Sache. Das könnte man doch
auch dann machen, wenn in C++ das Verhalten des = aus C für elementare
Datentypen übernommen worden wäre.
|
Dann hätte man halt eine Sonderregel gebraucht, die speziell abhängig davon,
ob es ein elementarer Typ ist, entweder einen L-Wert draus macht oder einen
R-Wert. Da ist es einfacher, so eine Unterscheidung bleiben zu lassen und
alle Typen in der Hinsicht gleich zu behandeln. Ich wüßte auf die Schnelle
nicht ganz, welche Auswirkungen das hätte, aber z.B. in Templates könnte
ich mir vorstellen, daß so eine Unterscheidung den einen oder anderen
Fallstrick aufwerfen könnte.
| Quote: | Ich würde nach wie vor einen Zuweisungsoperator so deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich besondere
Gründe habe, den Zuweisungsausdruck zu einem L-Wert machen zu wollen.
|
Ich lasse das const links meistens weg, da ich keinen Grund sehe, so eine
Einschränkung zu machen.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Klaus Schroeder Guest
|
Posted: Fri Mar 24, 2006 10:21 pm Post subject: Re: Zuweisungsoperator |
|
|
Rolf Magnus schrieb:
| Quote: |
Dann hätte man halt eine Sonderregel gebraucht, die speziell abhängig davon,
ob es ein elementarer Typ ist, entweder einen L-Wert draus macht oder einen
R-Wert. Da ist es einfacher, so eine Unterscheidung bleiben zu lassen und
alle Typen in der Hinsicht gleich zu behandeln. Ich wüßte auf die Schnelle
nicht ganz, welche Auswirkungen das hätte, aber z.B. in Templates könnte
ich mir vorstellen, daß so eine Unterscheidung den einen oder anderen
Fallstrick aufwerfen könnte.
Man braucht doch keine Sonderegelung. Also: |
1. Weil(!) in C++ ein Ausdruck wie (z = y) für elementare Datentypen ein
L-Wert ist(!), verstehe ich auch, dass man in Übereinstimmung damit auch
für benutzerdefinierte Datentypen T deklariert:
T & operator= (const T &);
(Es sei denn, man hat besondere Gründe, es anders zu machen.)
2. Wenn in C++ das Verhalten von C, nach dem (z = y) kein L-Wert ist,
übernommen worden wäre(!), würde(!) man auch in Übereinstimmung damit
für benutzerdefinierte Datentypen deklarieren:
const T & operator= (const T &);
(Letzteres habe ich - irrtümlicherweise - jahrelang gemacht).
Meine Frage war eigentlich: Warum(!) wurde das Verhalten von C, nach dem
(z = y) kein L-Wert ist, in C++ nicht übernommen? Das hat doch
wahrscheinlich einen tieferen Grund.
| Quote: | Ich würde nach wie vor einen Zuweisungsoperator so deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich besondere
Gründe habe, den Zuweisungsausdruck zu einem L-Wert machen zu wollen.
Ich lasse das const links meistens weg, da ich keinen Grund sehe, so eine
Einschränkung zu machen.
Na, den sehe ich schon. Damit so etwas wie (z = y) = x; nicht möglich ist! |
MfG, Klaus
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Sat Mar 25, 2006 11:06 am Post subject: Re: Zuweisungsoperator |
|
|
Klaus Schroeder wrote:
| Quote: | Rolf Magnus schrieb:
Dann hätte man halt eine Sonderregel gebraucht, die speziell abhängig
davon, ob es ein elementarer Typ ist, entweder einen L-Wert draus macht
oder einen R-Wert. Da ist es einfacher, so eine Unterscheidung bleiben zu
lassen und alle Typen in der Hinsicht gleich zu behandeln. Ich wüßte auf
die Schnelle nicht ganz, welche Auswirkungen das hätte, aber z.B. in
Templates könnte ich mir vorstellen, daß so eine Unterscheidung den einen
oder anderen Fallstrick aufwerfen könnte.
Man braucht doch keine Sonderegelung. Also:
1. Weil(!) in C++ ein Ausdruck wie (z = y) für elementare Datentypen ein
L-Wert ist(!), verstehe ich auch, dass man in Übereinstimmung damit auch
für benutzerdefinierte Datentypen T deklariert:
T & operator= (const T &);
(Es sei denn, man hat besondere Gründe, es anders zu machen.)
|
Ich hätte es genau anders herum gesehen. Weil man bei benutzerdefinierten
Typen üblicherweise eine Referenz und damit einen lvalue aus operator=
zurückgibt, hat man das auch für die elementaren Typen übernommen, statt
diese anders zu behandeln. Ist bei operator++ ja ähnlich. In C gibt er
immer einen rvalue zurück, während in C++ die präfix-Version einen lvalue
zurückgibt.
| Quote: | 2. Wenn in C++ das Verhalten von C, nach dem (z = y) kein L-Wert ist,
übernommen worden wäre(!), würde(!) man auch in Übereinstimmung damit
für benutzerdefinierte Datentypen deklarieren:
const T & operator= (const T &);
|
Das ist, wie Markus schon angemerkt hat, immer noch ein lvalue, aber
"non-modifyable". Das hätte man natürlich auch für die elementaren Typen
machen können. Warum das scheinbar nicht der Fall ist, weiß ich nicht.
| Quote: | (Letzteres habe ich - irrtümlicherweise - jahrelang gemacht).
Meine Frage war eigentlich: Warum(!) wurde das Verhalten von C, nach dem
(z = y) kein L-Wert ist, in C++ nicht übernommen? Das hat doch
wahrscheinlich einen tieferen Grund.
|
Siehe oben.
| Quote: | Ich würde nach wie vor einen Zuweisungsoperator so deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich besondere
Gründe habe, den Zuweisungsausdruck zu einem L-Wert machen zu wollen.
Ich lasse das const links meistens weg, da ich keinen Grund sehe, so eine
Einschränkung zu machen.
Na, den sehe ich schon. Damit so etwas wie (z = y) = x; nicht möglich ist!
|
Man muß nicht alles unterbinden, das keinen Sinn ergibt. Das wäre in C++
auch sehr schwierig und schränkt manchmal auch Dinge ein, an die man
vielleicht gar nicht dacht, und auf einmal fluchen die Leute über deine
Klasse. Letztendlich werden Klassen entgegen manchen Gerüchten durchaus von
denkenden Menschen benutzt ;-)
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Rolf Magnus Guest
|
Posted: Sat Mar 25, 2006 11:06 am Post subject: Re: Zuweisungsoperator |
|
|
Markus Moll wrote:
| Quote: | Hallo
Rolf Magnus wrote:
Klaus Schroeder wrote:
Ich würde nach wie vor einen Zuweisungsoperator so deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich besondere
Gründe habe, den Zuweisungsausdruck zu einem L-Wert machen zu wollen.
Ich lasse das const links meistens weg, da ich keinen Grund sehe, so eine
Einschränkung zu machen.
Ich auch, aber was anderes: ist das Ergebnis nicht immer noch ein lvalue?
|
Hmm, doch, müßte einer sein. Ist halt non-modifyable, aber dennoch ein
lvalue. Soweit ich weiß, ist's ein lvalue, wenn man die Adresse davon
ermitteln kann.
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Thomas Dorner Guest
|
Posted: Sat Mar 25, 2006 11:26 pm Post subject: Re: Zuweisungsoperator |
|
|
Hallo Klaus!
| Quote: | Ich lasse das const links meistens weg, da ich keinen Grund sehe, so eine
Einschränkung zu machen.
Na, den sehe ich schon. Damit so etwas wie (z = y) = x; nicht möglich ist!
|
Damit ist aber auch sowas wie
(z = y) += x
usw. nicht möglich. Als kompaktere Schreibweise für
z = y;
z += x;
kann sowas manchmal ganz nützlich sein. (Und ich habe ein
Klassentemplate, wo das schneller arbeitet als ein "z = y + x".)
Viele Grüße, Thomas
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
Klaus Schroeder Guest
|
Posted: Sun Mar 26, 2006 10:15 pm Post subject: Re: Zuweisungsoperator |
|
|
Thomas Dorner schrieb:
| Quote: | Damit ist aber auch sowas wie
(z = y) += x
usw. nicht möglich. Als kompaktere Schreibweise für
z = y;
z += x;
kann sowas manchmal ganz nützlich sein. (Und ich habe ein
Klassentemplate, wo das schneller arbeitet als ein "z = y + x".)
Das Beispiel leuchtet mir ein. Zumindest kann man es hier gebrauchen. Ob |
dieser Optimierungswunsch historisch der Grund für diese Änderung war,
weiß ich zwar nicht, aber es ist durchaus denkbar.
Auf jeden Fall ist das eine logische Erklärung.
Vielen Dank
Klaus Schröder
| Quote: | Viele Grüße, Thomas
|
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Mon Mar 27, 2006 10:06 am Post subject: Re: Zuweisungsoperator |
|
|
Rolf Magnus wrote:
| Quote: | Klaus Schroeder wrote:
In C hat es in der Tat keinen Sinn gemacht, weil da = ein
definiertes Verhalten fuer alle Operanden hatte, welche die
erste Zuweisung semantisch zu einem no-op machen wuerde --
in C++ kann man das Verhalten jedoch beliebig abaendern und
damit kann (z = y) = x; etwas ganz anderes sein als z = x;.
Auch in C++ hat = für elementare Datentypen (!) ein
definiertes Verhalten für alle Operanden und auch dort wird
in dem angegebenen Programmbeispiel (z = y) zu einem
"no-op". M.a.W. der Ausdruck (z = y) = x im Programmbeispiel
ist und bleibt ein Nonsense. Dass man bei der Überladung des
Zuweisungsoperators für einen selbstdefinierten Datentyp ein
beliebiges Verhalten definieren kann, also auch die
Bewertung von (z = y) als L-Wert, wenn man es für
wünschenswert hält, ist doch eine ganz andere Sache. Das
könnte man doch auch dann machen, wenn in C++ das Verhalten
des = aus C für elementare Datentypen übernommen worden
wäre.
Dann hätte man halt eine Sonderregel gebraucht, die speziell
abhängig davon, ob es ein elementarer Typ ist, entweder einen
L-Wert draus macht oder einen R-Wert.
|
Sonderregeln hat man sowieso. Der Ausdruck »(a = b) = c« ist bei
eingebauten Typen vorboten, nicht aber bei Klassentypen.
Wie Klaus sehe ich keine Interesse an so einem Ausdruck. Ich
denke auch, dass er nicht der Grunde ist, warum Zuweisungen
plötzlich L-Value geworden sind. Es hat viel mehr damit zu tun,
glaube ich, dass man in C++ Referenzen zurückgeben können, und
dass in gewissen Fällen kann etwas wie »return a = b« sinnvoll
sein, auch wenn die Funktion eine Referenz zurückliefert (und
auch dann, wenn a einen Grundtyp hat).
| Quote: | Da ist es einfacher, so eine Unterscheidung bleiben zu lassen
und alle Typen in der Hinsicht gleich zu behandeln. Ich wüßte
auf die Schnelle nicht ganz, welche Auswirkungen das hätte,
aber z.B. in Templates könnte ich mir vorstellen, daß so eine
Unterscheidung den einen oder anderen Fallstrick aufwerfen
könnte.
Ich würde nach wie vor einen Zuweisungsoperator so
deklarieren:
const MeinTyp & operator= (const MeinTyp &);
und ich würde davon nur dann abweichen, wenn ich wirklich
besondere Gründe habe, den Zuweisungsausdruck zu einem
L-Wert machen zu wollen.
Ich lasse das const links meistens weg, da ich keinen Grund
sehe, so eine Einschränkung zu machen.
|
Ich lasse das const weg, halt weil damit meine Operatore näher
an den eingebauten Operatore hält, und also die Erwartungen des
Benutzers meist entspricht. Ob gut ist, ist eine andere Frage,
aber es scheint mir in keinem Fall schlecht genug, dass man davon
abweichen muss.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Mon Mar 27, 2006 10:06 am Post subject: Re: Zuweisungsoperator |
|
|
Thomas Dorner wrote:
| Quote: | Ich lasse das const links meistens weg, da ich keinen Grund
sehe, so eine Einschränkung zu machen.
Na, den sehe ich schon. Damit so etwas wie (z = y) = x; nicht
möglich ist!
Damit ist aber auch sowas wie
(z = y) += x
usw. nicht möglich. Als kompaktere Schreibweise für
z = y;
z += x;
kann sowas manchmal ganz nützlich sein. (Und ich habe ein
Klassentemplate, wo das schneller arbeitet als ein "z = y +
x".)
|
Vielleicht, aber in so fern, dass so was mit einem Grundtyp
nicht möglich ist, bin ich skeptisch, ob man es in einem
Template benutzen soll.
Es ist wichtig, was mit den Grundtypen passsiert, nicht außer
Betracht zu lassen. Hat man:
double x, y, z ;
(x = y) += z ;
Dann ist der Code illegal, ob in C oder in C++. Der Unterschied
ist nur, dass in C muss der Compiler eine Fehlermeldung
herausbringen, wohingegen ist er in C++ nur undefiniertes
Verhalten. In diesem Fall mindestens muss man zugeben, dass die
C-Regel einen bedeutenden Vorteil hat.
In der Praxis, das Eingize, was mat mit dem l-Value als l-Value
machen kann, ist seine Adresse zu nehmen, also »&(x = y)«. Oder
ihn an eine Referenz zu binden, ohne Temporär.
Ich denke, dass dieses Letzte am bedeutendsten ist. Wenn man so
etwas wie:
double & r = x = y ;
schreibt (oder »x = y« als Rückgabe einer Funktion mit
Referenz-Type benutzt), erwartet man nicht auf einen Temporär.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|