Wie es aussieht, kann man in C++ keine Objekte als Rückgabewert haben.
Wenn ich nun eine Funktion habe, die mir aus vier Integern einen Vector
erstellt und ich diesen Vector weiterverwenden will, wie bekomme ich ihn
"aus der Methode raus"? Ich dachte da zuerst, der Methode einen Pointer
zu übergeben, sodass die Methode diesen für die Ergebnisse benutzt. Ist
dieser Ansatz richtig? Hat bei mir leider nicht geklappt ... Kann man in
C++ eine Referenz auf ein Objekt einer Klasse zurückgeben? Oder wie wird
das allgemein gehandhabt?
Java lässt grüßen ... ;)
Maxim schrieb:> Wie es aussieht, kann man in C++ keine Objekte als Rückgabewert haben.
Nicht? Wär aber sonderbar...
> Wenn ich nun eine Funktion habe, die mir aus vier Integern einen Vector> erstellt und ich diesen Vector weiterverwenden will, wie bekomme ich ihn> "aus der Methode raus"? Ich dachte da zuerst, der Methode einen Pointer> zu übergeben, sodass die Methode diesen für die Ergebnisse benutzt.
Kann man machen, muss man allerdings aufpassen, dass der Zeiger nach
Verlassen der Methode auch noch irgendwohin zeigt. Bedenke, dass die
Lebensdauer lokaler Variablen und Objekte dann nämlich endet!
> Ist> dieser Ansatz richtig? Hat bei mir leider nicht geklappt ... Kann man in> C++ eine Referenz auf ein Objekt einer Klasse zurückgeben?
Kann man, dann gilt aber gleiches. Auch eine Referenz kann auf ein nicht
mehr existierendes Objekt verweisen. Das passt den meisten OOP-Priestern
zwar nicht in den Kram, ist aber so.
> Oder wie wird> das allgemein gehandhabt?
Ganz 'normal' halt -- entweder sich vorher einigen, wer ein Objekt
erzeugt und wer es zerstört: Dann kann man auch ein neu erzeugtes Objekt
als Zeiger zurückgeben (so von wegen 'return new ...'. Oder ein lokales
Objekt direkt zurückgeben, das wird dann eben zur Kopie. Oder eine
Referenz auf ein statisches Objekt -- ja nachdem, was grad passt.
Maxim schrieb:> Wie es aussieht, kann man in C++ keine Objekte als Rückgabewert haben.
Welches spezielle C++ hast du den wo das nicht geht?
Also bei mir klappt das wunderbar ;)
Sven P. schrieb:> Oder ein lokales> Objekt direkt zurückgeben, das wird dann eben zur Kopie.
Davor sollte man allerdings keine Scheu haben.
Der C++ Weg ist es, ganz einfach das Objekt zurückzugeben.
Es gibt eine einzige Optimierung, die im C++ Standard erwähnt und
ausdrücklich erlaubt wird. Die sog. Named Return Value Optimization
Sie kommt hier zum tragen
1
classA
2
{
3
};
4
5
6
Afoo()
7
{
8
AobjOfA;
9
10
returnobjOfA;
11
}
12
13
intmain()
14
{
15
Atest;
16
17
test=foo();
18
}
ZUnächst mal würde man annehmen, dass das Objekt in der Funktion kopiert
wird, diese Kopie aus der Funktion herausgereicht wird, dort mittels
einem op= zugewiesen wird und danach das temporäre Objekt zerstört wird.
Alles in allem eine aufwändige Sache.
Wenn da nicht die NRVO wäre.
Sie erlaubt explizit, dass der Compiler da ein paar Schritte
überspringt, zb indem das temporäre Objekt nicht erzeugt wird, sondern
test seinen Zuweisung direkt von objOfA erhält. Eine weitere Möglichkeit
ist es, dass der Compiler die Situation so löst, dass er eine Referenz
auf test in die Funktion hinein übergibt, und objOfA inplace im test
Objekt konstruiert.
In all diesen Fällen erfolgt dann kein Aufruf des Copy Constructors bzw.
von Destruktoren. Und das ist explizit erlaubt, selbst wenn diese Member
Funktionen Nebeneffekte haben (*)
Fazit: keine Angst davor, Objekte direkt aus einer Funktion heraus als
Return Wert zu liefern. Compiler haben Methoden, wie sie auch diese
Fälle schnell machen können.
(*) Das ist einer der Gründe, warum man nicht zu clever sein sollte und
im Copy Construktor andere Funktionalität als einfach nur 'Erzeuge eine
Kopie des Objektes' unterbringen sollte.
jua schrieb:> Dass ein Compiler es möglicherweise optimieren kann, ist IMO kein guter> Grund, ineffizienten Code zu schreiben.
Was ist bei dir ineffizient?
Letzten Endes, wenn mein dein Argument ins Extrem treibt, bedeutet es:
Alles ausser Assembler ist Müll :-)
Mach dir um Effizenz keine Sorgen. C++ Compiler sind viel besser als du
glaubst. Schon so mancher C Trickser, der auf seiner Überlegenheit
gepocht hat, hat sein blaues Wunder erlebt, als der C++ Compiler aus
einem ordinärem, schön geschriebenen, kanonischen C++ Programm etwas
erzeugt hat, was seine 'hoch-optimierte' C-Lösung alt aussehen hat
lassen. Von "korrekter Fehlerbehandlung" versus "wieder einmal in C
nicht freigegebenem Speicher" reden wir erst mal gar nicht.
Wenn du Effizienz haben willst, denn leg dein Augenmerk auf Algorithmen.
Die Details der Implementierung überlass getrost dem Compiler.
jua schrieb:> Dass ein Compiler es möglicherweise optimieren kann, ist IMO kein guter> Grund, ineffizienten Code zu schreiben.
Daß eigentlich alle gängigen Compiler hier den effizienten Weg
automatisch verwenden, ist ein guter Grund, einfacheren, lesbareren Code
zu schreiben. Im Falle von Operatorüberladung, z.B. beim Operator+
geht's auch gar nicht anders.
Maxim schrieb:> Wie es aussieht, kann man in C++ keine Objekte als Rückgabewert haben.
Du kannst das vielleicht nicht, aber "man" kann das schon ;-)
> Wenn ich nun eine Funktion habe, die mir aus vier Integern einen Vector> erstellt und ich diesen Vector weiterverwenden will, wie bekomme ich> ihn "aus der Methode raus"?
Nur am Rande: In C++ gibt es keine "Methoden". Es gibt nur Funktionen.
Stroustrup verwendet das Wort "method" nur in Anführungszeichen und rät
von der Verwendung ab.
Es gibt auch mehrere unterschiedliche Meinungen darüber, was genau damit
in C++ überhaupt gemeint ist.
> Ich dachte da zuerst, der Methode einen Pointer zu übergeben, sodass> die Methode diesen für die Ergebnisse benutzt. Ist> dieser Ansatz richtig? Hat bei mir leider nicht geklappt ...
Was heißt "hat nicht geklappt"? Was ist passiert?
> Kann man in C++ eine Referenz auf ein Objekt einer Klasse zurückgeben?
Ja. Allerdings muß man dabei selbst darauf achten, daß das Objekt so
lange gültig bleibt, wie die Referenz benutzt wird. Das bedeutet z.B.
daß es grundsätzlich sinnlos ist, Referenzen auf lokale (non-static)
Variablen zurückzugeben, da diese Variablen automatisch zerstört werden,
bevor die Referenz überhaupt verwendet werden kann.
> Oder wie wird das allgemein gehandhabt?>> Java lässt grüßen ... ;)
Generell besteht bezüglich des Speicherhandling von Objekten ein großer
Unterschied zwischen C++ und Java. C++ kennt drei Arten von Speicher,
nämlich statisch, automatisch und dynamisch. Statische Variablen
existieren praktisch bis zum Programmende (das sind globale Variablen,
als static deklarierte Member-Variablen oder als static deklarierte
lokale Variablen). Automatische Variablen werden beim Verlassen ihres
Scope zerstört. Das sind lokale non-static-Variablen. Dynamische Objekte
werden mit new angelegt und existieren solange, bis sie mit delete
wieder zerstört werden.
Karl heinz Buchegger schrieb:> jua schrieb:>> Dass ein Compiler es möglicherweise optimieren kann, ist IMO kein guter>> Grund, ineffizienten Code zu schreiben.> Was ist bei dir ineffizient?
Ineffizient ist, wenn der Compiler die Kopieroperation doch macht, von
der man dachte, er wuerde sie wegoptimieren.
> Letzten Endes, wenn mein dein Argument ins Extrem treibt, bedeutet es:> Alles ausser Assembler ist Müll :-)
Jedes Argument, dass man in's Extrem treibt, wird absurd. Deswegen
laesst man das, wenn man eine sinnvolle Diskussion fuehren will.
> Mach dir um Effizenz keine Sorgen. C++ Compiler sind viel besser als du> glaubst.
Sie sind viel schlechter, als du glaubst. Und noch dazu ist das Wissen
von einem Compiler auf den anderen nicht einfach uebertragbar. Noch
nicht einmal von einer Version auf die andere. Schon deshalb ist es
fahrlaessig, sich auf solche Eigenschaften zu verlassen.
> Schon so mancher C Trickser, der auf seiner Überlegenheit> gepocht hat, hat sein blaues Wunder erlebt, als der C++ Compiler aus> einem ordinärem, schön geschriebenen, kanonischen C++ Programm etwas> erzeugt hat, was seine 'hoch-optimierte' C-Lösung alt aussehen hat> lassen.
Stimmt. Deswegen wird der Umkehrschluss aber noch lange nicht zulaessig.
Ich empfehle einfach mal etwas Praxis. Wer schon mal gezwungen war, dem
Compiler genau auf die Finger zu schauen, kann nur die Haende ueber dem
Kopf zusammenschlagen, was da manchmal bei rauskommt.
> Von "korrekter Fehlerbehandlung" versus "wieder einmal in C> nicht freigegebenem Speicher" reden wir erst mal gar nicht.
Ach komm, immer der gleiche Spruch. Wer so viel Angst vor Speicherlecks
hat, muss sich entweder mal auf den Hintern setzen und sein Programm in
den Griff kriegen (was dann voellig ueberraschend auch allgemein die
Programmqualitaet hebt), oder eine Sprache verwenden, die diesem
persoenlichen Problem entgegenkommt.
> Wenn du Effizienz haben willst, denn leg dein Augenmerk auf Algorithmen.
Da gehoeren vernueftige Parameteruebergaben dazu.
Rolf Magnus schrieb:> jua schrieb:> Daß eigentlich alle gängigen Compiler hier den effizienten Weg> automatisch verwenden, ist ein guter Grund, einfacheren, lesbareren Code> zu schreiben.
Einfach, lesbar und idiotentsicher: Den zu fuellenden Vector einfach
uebergeben. Ob als Referenz oder Pointer ist mir schnuppe, auch wenn ich
den Pointer vorziehe.
> Im Falle von Operatorüberladung, z.B. beim Operator+ geht's auch gar nicht
anders.
Einfach, lesbar und Operatorueberladung passt nicht wirklich in einen
Absatz.
Peter Stegemann schrieb:> Einfach, lesbar und Operatorueberladung passt nicht wirklich in einen> Absatz.
Das kommt erstens drauf, ob man Operatorueberladung nutzt oder
missbraucht, und zweitens, ob man sie mag.
Es gibt nun wirklich Beispiele, wo sie die Lesbarkeit drastisch erhöhen.
(einstream << einwert gehört nicht unbedingt dazu)
Karl heinz Buchegger schrieb:> Mach dir um Effizenz keine Sorgen. C++ Compiler sind viel besser als du> glaubst.
Heh, das ist einer meiner Lieblingssprüche, direkt neben "Heutige
Computer sind sowieso so schnell, dass [...]".
Compiler können vieles, man sollte sich aber im Allgemeinen nicht darauf
verlassen. Das kann man tun bei simplen Compiler-Optimierungen --
constant folding, constant propagation, diese Art von Dingen. Bei
komplexeren Konstrukten wird es jedoch unübersichtlich...
Und natürlich sind Algorithmen entscheident, aber auch eine effiziente
Implementierung kann einen riesigen Unterschied machen. Einfaches
Beispiel, folgende zwei Funktionen:
Die Funktion Nr. 1 ist auf meinem Rechner mehr als 3 mal schneller als
Funktion Nr. 2. Das Ergebnis ist das gleiche. Nun die Preisfrage: Warum
ist Variante 1 so viel schneller und warum kann der Compiler es nicht
optimieren? In der Antwort auf diese Frage erkennt man, warum die
Implementierung nicht unwichtig ist...
Klaus Wachtler schrieb:> Das kommt erstens drauf, ob man Operatorueberladung nutzt oder> missbraucht, und zweitens, ob man sie mag.> Es gibt nun wirklich Beispiele, wo sie die Lesbarkeit drastisch erhöhen.> (einstream << einwert gehört nicht unbedingt dazu)
Ernst hat ja schon ein Beispiel genannt. Und mit Verlaub, viele
sinnvolle Anwendungen bleiben nicht mehr uebrig, die
Missbrauchsmoeglichkeiten ueberwiegen bei weitem.
Wenn ich alle Gelegenheiten zusammenzaehle, bei denen ich in meinem
Programmiererleben Operatorueberladung habe sinnvoll einsetzen koennen,
dann komme ich auf: Einmal.
Frage mich nicht nach den Faellen, wo Operatorueberladung nur zu Chaos
und schweren Fehlern gefuehrt hat, da kann ich nur sagen: Fast jedesmal.
Wirklich zaehlen kann ich das nicht mehr.
Peter Stegemann schrieb:> Ernst hat ja schon ein Beispiel genannt. Und mit Verlaub, viele> sinnvolle Anwendungen bleiben nicht mehr uebrig, die> Missbrauchsmoeglichkeiten ueberwiegen bei weitem.
Es kommt halt drauf, was man gerade programmiert.
Wenn ich mir neue Datentypen schaffe, mit denen gerechnet werden
soll (z.B. die Festkommageschichte, die ich neulich mal machte),
ist Operatorueberladung einfach Gold wert.
Wenn es in 99% der Programm keinen Sinn macht, muß man es
halt bei diesen 99% nicht verwenden.
>> Wenn ich alle Gelegenheiten zusammenzaehle, bei denen ich in meinem> Programmiererleben Operatorueberladung habe sinnvoll einsetzen koennen,> dann komme ich auf: Einmal.
Ein paar mehr hätte ich da schon zu bieten...
>> Frage mich nicht nach den Faellen, wo Operatorueberladung nur zu Chaos> und schweren Fehlern gefuehrt hat, da kann ich nur sagen: Fast jedesmal.> Wirklich zaehlen kann ich das nicht mehr.
Mit dieser Begründung darfst du auch keine Zeiger nehmen :-)
---
Das alles ändert aber doch nichts daran, daß es legitim und sogar
explizit vorgesehen ist, in Funktionen und/oder Methoden Werte
zurückzugeben.
Ich verstehe nicht, wieso man das jetzt auf einmal verbieten soll.
Außer daß man es im Einzelfall "nicht mag" sehe ich irgendwie
kein echtes Argument dagegen.
Diese Diskussion erinnert mich an eine alte Geschichte, noch aus dem
Studium. Das muss so 14 Jahre her sein, da hat ein Mitstudent auch ein
C++-Programm geschrieben, wo er alle Objekte als Kopien uebergeben hat.
Wirklich ueberraschend war das nicht, da der Professor didaktisch eine
Null war und C++ sehr abstrakt gelehrt hat. Das endete dann auch noch in
anderen Katastrophen wie Endlosrekursionen (waeren C++-Methoden-Aufrufe
wirklich Messages, wie es so schoen abstrakt erklaert wurde, waere das
ja gegangen). Der Kollege hat sich auch gewundert, warum sein Programm
so langsam ist.
Wer nun meint, das sei eine olle Kamelle und die Compiler seien heute ja
schon viel weiter:
1) Wenn ich jedesmal, wenn mir jemand erklaert heute sei ja sowas kein
Problem mehr, mich darauf einlasse und das ueberpruefe, tue ich nichts
anderes mehr.
2) In der Praxis ist es ueberhaupt nichts Besonderes, auf so alte
Compiler zu stossen.
3) Es gleich richtig zu machen, ist genauso einfach.
Klaus Wachtler schrieb:> Peter Stegemann schrieb:>> Frage mich nicht nach den Faellen, wo Operatorueberladung nur zu Chaos>> und schweren Fehlern gefuehrt hat, da kann ich nur sagen: Fast jedesmal.>> Wirklich zaehlen kann ich das nicht mehr.> Mit dieser Begründung darfst du auch keine Zeiger nehmen :-)
Doch. Sie sind ein grundlegender Sprachbestandteil, klar definiert und
machen, was sie sollen - es sei denn, jemand ueberlaedt einen Operator.
Dann reagiert Code, der aussieht wie jeder andere Code, ploetzlich
anders.
> Das alles ändert aber doch nichts daran, daß es legitim und sogar> explizit vorgesehen ist, in Funktionen und/oder Methoden Werte> zurückzugeben.
Ohne wuerden viele Methoden ja wenig Sinn ergeben :-)
> Ich verstehe nicht, wieso man das jetzt auf einmal verbieten soll.
Wer sagt denn, dass es verboten werden soll? Aber andersrum muss man
doch auch mal fragen duerfen: Hat die Sprache das jetzt unbedingt
gebraucht? Denn C++ wird nach wie vor von wildgewordenen Gremien
"verbessert".
> Außer daß man es im Einzelfall "nicht mag" sehe ich irgendwie> kein echtes Argument dagegen.
Operatorueberladung ist ein maechtiges Schwert und fuehrt sehr leicht zu
extrem unangenehmen Fehlerquellen. Und leider werden sie von vielen als
tolle, harmlose Kosmetik angepriesen, die den Code huebscher macht und
entsprechend hemmungslos eingesetzt. Und wenn man dann beruflich solchen
Mist aufraeumen muss, dann geht es nicht mehr um "moegen" oder "nicht
moegen" sondern um ein immer mehr um sich greifendes Aergernis.
Peter Stegemann schrieb:> Diese Diskussion erinnert mich an eine alte Geschichte, noch aus dem> ...
Wie soll in dem Punkt ein Compiler weiter sein?
Man kann Parameter als Zeiger oder Referenzen oder Wert
übergeben; wenn man die falsche Wahl trifft, kann der Compiler
nichts dafür.
Aber was hat das jetzt mit der Rückgabe von Objekten zu tun? :-)
Peter Stegemann schrieb:> Dann reagiert Code, der aussieht wie jeder andere Code, ploetzlich> anders.
Das ist aber eher ein Problem des Betrachters.
Wenn man mit + nur int- oder double-Addition assoziiert, hat
man Pech.
Hat man dagegen im Kopf, daß ein + halt ein Operatoraufruf ist,
sind die Folgen nicht überraschender als bei einer Funktion add().
Der sehe ich beim Aufruf auch nicht an, ob sie wirklich addiert
oder was ganz anderes macht.
Peter Stegemann schrieb:> Operatorueberladung ist ein maechtiges Schwert und fuehrt sehr leicht zu> extrem unangenehmen Fehlerquellen. Und leider werden sie von vielen als> tolle, harmlose Kosmetik angepriesen, die den Code huebscher macht und> entsprechend hemmungslos eingesetzt. Und wenn man dann beruflich solchen> Mist aufraeumen muss, dann geht es nicht mehr um "moegen" oder "nicht> moegen" sondern um ein immer mehr um sich greifendes Aergernis.
Aber das ist doch mit allen Möglichkeiten von C++ so.
Es gibt viele Leute, die sie nicht verstanden haben und
nur herumpfuschen.
Nur weil viele Deppen nicht mit scharfen Werkzeugen
umgehen können, will ich doch nicht mit der Nagelfeile einen
Motorblock fräsen.
Klaus Wachtler schrieb:> Wie soll in dem Punkt ein Compiler weiter sein?> Man kann Parameter als Zeiger oder Referenzen oder Wert> übergeben; wenn man die falsche Wahl trifft, kann der Compiler> nichts dafür.>> Aber was hat das jetzt mit der Rückgabe von Objekten zu tun? :-)
Zitat: "Fazit: keine Angst davor, Objekte direkt aus einer Funktion
heraus als Return Wert zu liefern. Compiler haben Methoden, wie sie auch
diese Fälle schnell machen können."
Klaus Wachtler schrieb:> Das ist aber eher ein Problem des Betrachters.> Wenn man mit + nur int- oder double-Addition assoziiert, hat> man Pech.
Es geht nicht nur um + und -. So richtig Chaos kannst du mit ==, () und
-> anrichten. Hat da der werte Leser auch Pech?
> Aber das ist doch mit allen Möglichkeiten von C++ so.> Es gibt viele Leute, die sie nicht verstanden haben und> nur herumpfuschen.
Deswegen muss man das aber nicht noch unterstuetzen und das als schick
und easy propagieren. Du legst einem Kind doch auch kein Messer hin und
sagst: "Guck mal, damit kann man total toll schnippeln, das musst du
unbedingt immer dabei haben!" Und dieser leichtfertige Umgang ist eben
ein trauriger Fakt.
> Nur weil viele Deppen nicht mit scharfen Werkzeugen> umgehen können, will ich doch nicht mit der Nagelfeile einen> Motorblock fräsen.
Ja, den Spruch habe ich schon oft gehoert. Das Resultat sind dann
regelmaessig abgespacte Konstruktionen, bei denen die neuesten Patterns
und die coolsten Sprachfeatures umgesetzt werden. Nur leider kann das
sonst kein Schwein mehr lesen, geschweige denn warten.
Wenn du mich beeindrucken willst: KIS.
Peter Stegemann schrieb:> Diese Diskussion erinnert mich an eine alte Geschichte, noch aus dem> Studium. Das muss so 14 Jahre her sein, da hat ein Mitstudent auch ein> C++-Programm geschrieben, wo er alle Objekte als Kopien uebergeben hat.
Du vergleichst hier Äpfel mit Birnen.
Von Objekten in eine Funktion hineinübergeben war nicht die Rede.
Und da habe ich das Valuepassing auch nicht schön geredet.
Es geht um Return Werte!
Argument Passig ist eine andere Geschichte
* Handelt es sich um einen skalaren Typ, wie int, long ...
ja: Übergib per Value
Nein: Brauchst du die Möglichkeit, der Funktion anzeigen zu können:
Ich hab nichts für dich?
ja: Übergib einen Pointer
Nein: Muss die Funktion den Wert beim Aufrufer verändern können?
ja: Übergib eine Referenz
Nein: Übergib eine const Referenz
Mit diesem Entscheidungsbaum hast du alles was du brauchst, in der
effizientesten Art.
Operator Overloadiung:
Nur weil du keine Klassen gefunden hast, bei denen Operator Overloadding
Sinn macht, heist das ja noch lange nicht, dass andere so etwas nicht
brauchen können.
Vektoren, Matrizen, Sowohl 2D als auch 3D, Operationen mit Geometrien
(Boolsche Operationen auf Flächen/Körpern), ...
Was denkst du, wie wunderbar schön, kurz, übersichtlich und nicht
zuletzt fehlerunanfällig sich das in CAD-Code benutzen lässt.
Dagegen sind die alten C-Kamellen mit Unmengen an Funktionsaufrufen
reinster Unfug dagegen.
Herz was willst du mehr. Und ja, ich verlass mich darauf, dass im
letzten Fall der Compiler die komplette Berechnung von x wegoptimiert.
Und ja, ich verlasse mich darauf, dass der Compiler bei der
Initialisierung von c das temporäre Objekt wegoptimiert. (Und seit 10
Jahren hab ich keinen Compiler mehr gesehen, der es nicht getan hätte.
Davor hab ich nicht im Assemblercode nachgesehen)
C++, wenn man die Sprache richtig benutzt, ist auf die Fähigkeiten des
Optimizers angewiesen. Die Compilerbauer wissen das und haben hart daran
gearbeitet. Es wäre dumm, die nicht zu benutzen, wenn man sich dadurch
das Leben leichter machen kann.
Und ja, man kann sich mit Operator Overloading selbst ein Bein stellen.
Genauso wie man sich ein Bein stellen kann, wenn man Unmengen an
Conversion Operatoren schreibt. Und? Man kann sich auch selbst mit einem
Revolver ins Bein schiessen.
Niemand sagt, dass man nach 2 Tagen C++ Grundkurs perfekt ist. Dazu gibt
es Lernphasen, in denen man lernt was man tun darf, tun soll und was man
besser nicht tut.
Peter Stegemann schrieb:> Wenn du mich beeindrucken willst: KIS.
Yep.
Keep it simple.
Aber dort wo eine Klasse verwendet wird! Das soll so simpel wie möglich
sein. Die Klasse darf (und soll auch) ruhig ein wenig Aufwand treiben um
das zu ermöglichen.
Wenn du mich beeindrucken willst: Dann schreib Klassen, die auf sich
selbst aufpassen und die verhindern, dass man sie missbräuchlich
verwenden kann.
Peter Stegemann schrieb:> Es geht nicht nur um + und -. So richtig Chaos kannst du mit ==, () und> -> anrichten. Hat da der werte Leser auch Pech?
Du hast den Komma Operator vergessen :-)
Aber im Ernst: Nur weil es ein paar Operatoren gibt, die man besser
nicht überlädt, heißt das noch lange nicht, das Operator Overloading als
Ganzes Teufelswerk ist.
> Deswegen muss man das aber nicht noch unterstuetzen und das als schick> und easy propagieren. Du legst einem Kind doch auch kein Messer hin und> sagst: "Guck mal, damit kann man total toll schnippeln, das musst du> unbedingt immer dabei haben!" Und dieser leichtfertige Umgang ist eben> ein trauriger Fakt.
Fakt ist, genauso wie wir es hier in Form von C jeden Tag sehen, dass
viele Leute C++ programmieren, ohne die Sprache zu kennen. Niemand
bestreitet dass es auch in C++ Fallen gibt. Das bedeutet aber nicht,
dass man grundsätzlich nicht in C++ programmieren kann. Und zwar nicht
auf die Art 'C mit Klassen', sondern so wie sich das die Erfinder
vorgestellt haben: In einer objektorientierten Art und Weise.
Peter Stegemann schrieb:>> Von "korrekter Fehlerbehandlung" versus "wieder einmal in C>> nicht freigegebenem Speicher" reden wir erst mal gar nicht.>> Ach komm, immer der gleiche Spruch.
Weil er leider immer noch ein Thema ist.
Es tut mir leid dir das sagen zu müssen, aber in den meisten hinreichend
großen C Programmen sind nun mal Speicherlecks. Solange es sich nur um
Lecks handelt geht es ja noch. Viel schlimmer ist es, wenn sich mal
wieder einer den Speicher niederbügelt.
Und mehr als einmal ist die Ursache dafür: Keine Organisation im Code
und wildes C Gehacke.
> Wer so viel Angst vor Speicherlecks> hat, muss sich entweder mal auf den Hintern setzen und sein Programm in> den Griff kriegen (was dann voellig ueberraschend auch allgemein die> Programmqualitaet hebt), oder eine Sprache verwenden, die diesem> persoenlichen Problem entgegenkommt.
Genau: zb C++ mit RAII Idiom.
>> Wenn du Effizienz haben willst, denn leg dein Augenmerk auf Algorithmen.>> Da gehoeren vernueftige Parameteruebergaben dazu.
Sorry.
Aber mit dieser Aussage bist du bei mir unten durch.
Karl heinz Buchegger schrieb:> Peter Stegemann schrieb:>> Diese Diskussion erinnert mich an eine alte Geschichte, noch aus dem>> Studium. Das muss so 14 Jahre her sein, da hat ein Mitstudent auch ein>> C++-Programm geschrieben, wo er alle Objekte als Kopien uebergeben hat.> Du vergleichst hier Äpfel mit Birnen.
Du greifst dir aus meinen ganzen Postings einen Satz raus, den man
einseitig interpretieren kann und reduzierst alles, was ich geschrieben
habe, darauf.
> Von Objekten in eine Funktion hineinübergeben war nicht die Rede.> Und da habe ich das Valuepassing auch nicht schön geredet.>> Es geht um Return Werte!
Das ist auch eine Uebergabe, eben von der aufgerufenen Funktion an den
Aufrufer.
> Argument Passig ist eine andere Geschichte
Jetzt erklaere dem Laien mal, warum die allgemeine Aussage von oben
"Mach dir um Effizenz keine Sorgen. C++ Compiler sind viel besser als du
glaubst.", hier ploetzlich nicht gilt.
> Operator Overloadiung:> Nur weil du keine Klassen gefunden hast, bei denen Operator Overloadding> Sinn macht, heist das ja noch lange nicht, dass andere so etwas nicht> brauchen können.
Du wiederholst hier nur, was Klaus schon geschrieben und ich schon
beantwortet habe.
> C++, wenn man die Sprache richtig benutzt, ist auf die Fähigkeiten des> Optimizers angewiesen. Die Compilerbauer wissen das und haben hart daran> gearbeitet. Es wäre dumm, die nicht zu benutzen, wenn man sich dadurch> das Leben leichter machen kann.
Sorry, aber solche Aussagen sind voellig praxisfern. Das solltest du mit
deiner Berufserfahrung eigentlich wissen. Bin ich dumm, wenn ich in
einem zig Jahre alten Grossprojekt den Compiler nicht austausche? Wenn
ich meinen Code ohne Mehraufwand so gestalte, dass er nicht vom letzten
Optimizertrick abhaengt? Oder bin ich nicht eher dumm, wenn ich mein
Gehirn abschalte und jede Feature der Sprache einsetze, nur weil es da
ist?
Karl heinz Buchegger schrieb:> Peter Stegemann schrieb:>> Ach komm, immer der gleiche Spruch.> Weil er leider immer noch ein Thema ist.> Es tut mir leid dir das sagen zu müssen, aber in den meisten hinreichend> großen C Programmen sind nun mal Speicherlecks. Solange es sich nur um> Lecks handelt geht es ja noch. Viel schlimmer ist es, wenn sich mal> wieder einer den Speicher niederbügelt.
Sprich bitte nur fuer deine Projekte. Im professionellen Umfeld gibt es
zur Not auch professionelle Tools. Und wer sich mit den damit
erreichbaren Ergebnissen nicht zufrieden geben kann: Es gibt Sprachen,
die diese Probleme wesentlich besser loesen, als jeder C++-Trick.
> Und mehr als einmal ist die Ursache dafür: Keine Organisation im Code> und wildes C Gehacke.
In diesen Faellen sind Speicherlecks nicht das Problem, sondern nur ein
Indikator. Wenn du die Speicherlecks trocken legst, ist die Applikation
immer noch kaputt. Du doktorst also an den Symptomen rum, statt die
Ursachen anzugehen.
>>> Wenn du Effizienz haben willst, denn leg dein Augenmerk auf Algorithmen.>> Da gehoeren vernueftige Parameteruebergaben dazu.> Sorry.> Aber mit dieser Aussage bist du bei mir unten durch.
Kein Argument, das mich ueberzeugt.
Peter Stegemann schrieb:>> Argument Passig ist eine andere Geschichte>> Jetzt erklaere dem Laien mal, warum die allgemeine Aussage von oben> "Mach dir um Effizenz keine Sorgen. C++ Compiler sind viel besser als du> glaubst.", hier ploetzlich nicht gilt.
Das war keine allgemeine Aussage.
Das war eine Aussage im Kontext von Return Wert passing.
Der ganze Thread hat sich anfangs darum gedreht. Mein ganzes Posting hat
sich darum gedreht:
Return Wert Passing und was der Compiler tun kann und tun darf, damit
man dort keinen Penalty zahlen muss.
Du bist derjenige, der den Kontext des Threads davon weg geholt hat!
> Oder bin in ich nicht eher dumm, wenn ich mein> Gehirn abschalte und jede Feature der Sprache einsetze, nur weil es da> ist?
Dinke für die Blumen.
Gute Nacht.
Schreib deine C Programme von mir aus mit 'C mit Klassen'. Aber lass
andere C++ programmieren. OK?
Karl heinz Buchegger schrieb:> Du bist derjenige, der den Kontext des Threads davon weg geholt hat!
Mach mal den Computer aus, rege dich ein wenig ab und lies morgen
nochmal in Ruhe nach, wie sich der Thread entwickelt hat und warum.
> Dinke für die Blumen.
Vergiss nicht, wer damit angefangen hat, anderen Dummheit zu
unterstellen.
Peter Stegemann schrieb:> Karl heinz Buchegger schrieb:>>> Du bist derjenige, der den Kontext des Threads davon weg geholt hat!>> Mach mal den Computer aus, rege dich ein wenig ab und lies morgen> nochmal in Ruhe nach, wie sich der Thread entwickelt hat und warum.
Und in der Zwischenzeit kannst du ja mal darüber nachdenken, wie
sinnvoll es ist, Sprachfeatures zu verdammen und die generelle
Empfehlungen 'alles ist ein Pointer' und 'Return by Pointer Passing' ist
das einzig Wahre, nur weil du in der durchaus bedauernswerten Situation
bist, himmelalten Code auf einem noch älteren Compiler warten zu müssen.
Der Rest der C++ Gemeinde benutzt ganz einfach C++ so wie es gedacht ist
und erfreut sich daran, dass sie neuere Compiler benutzen können, für
die diese Optimierungen nicht der Rede wert sind.