PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C++ Objekt als Rückgabewert


Apfelbaum
2010-10-27, 20:30:52
Guten Tag.
Ich habe mir C++ mehr oder weniger selbst beigebracht. Dies hat sein natürliches Ende darin gefunden, dass mein Programmierstil ein Verbrechen wider der hohen Zunft der Programmierkunst und mein Wissen was Grundlagen angeht unterirdisch ist. Hätte deswegen eine klitzekleine Frage.

Oft hab ich beobachtet, dass simple structs oder std::strings von Funktionen zurückgegeben werden. So wie in diesem Beispiel:
struct vec2
{
int x;
int y;
vec2(int x_, int y_) : x(x_), y(y_) {}
};

vec2 gibNullVec()
{
return vec2(0,0);
}

int main(gay args)
{
vec2 vector = gibNullVec();
// ...
return 0;
}

Funktionieren tut das alles. Die Werte stimmen. Doch ist hier alles koscher? Der Rückgabewert befindet sich vor der Rückgabe auf dem Stack (oder?). Wie kann der dann zurückgegeben werden, wenn die Funktion vorher beendet wird und der Stack undefiniert ist? Wird extra das komplette struct zwischengespeichert? Oder ist das einfach nur falsch?

Sollte dies korrekt sein, würde es dann auch mit class-Objekten und container-Objekten wie std::string funktionieren?

Sollte dies nicht korrekt sein, würde es dann korrekt sein, wenn ich die Funktion als inline definiere?

Danke schon einmal...

Gast
2010-10-27, 21:24:16
Guten Tag.
Ich habe mir C++ mehr oder weniger selbst beigebracht. Dies hat sein natürliches Ende darin gefunden, dass mein Programmierstil ein Verbrechen wider der hohen Zunft der Programmierkunst und mein Wissen was Grundlagen angeht unterirdisch ist. Hätte deswegen eine klitzekleine Frage.

Oft hab ich beobachtet, dass simple structs oder std::strings von Funktionen zurückgegeben werden. So wie in diesem Beispiel:


Funktionieren tut das alles. Die Werte stimmen. Doch ist hier alles koscher? Der Rückgabewert befindet sich vor der Rückgabe auf dem Stack (oder?). Wie kann der dann zurückgegeben werden, wenn die Funktion vorher beendet wird und der Stack undefiniert ist? Wird extra das komplette struct zwischengespeichert? Oder ist das einfach nur falsch?

Wo genau die Struct zu liegen kommt weiß ich auch nicht, ich würde sagen dort wo auch der Rückgabeparameter liegt wenn es ein int, char, float oder sonstwas ist. Für Mikroprozessoren ist es oft so dass die Rückgabeparameter in speziellen Registern landen, wie das bei x86 ist weiß ich nicht. Ist aber eigentlich egal, du kannst jedenfalls eine struct,class,wasauchimmer als Rückgabeparameter einer Funktion verwenden.

Sollte dies korrekt sein, würde es dann auch mit class-Objekten und container-Objekten wie std::string funktionieren?

Ja, es funktioniert mit allem möglichen. Wichtig ist hier nur dass die struct bzw. das Objekt einen gültigen copy-constructor hat, genau dieser wird nämlich bei statements wie

vec2 vector = gibNullVec();

aufgerufen. Der Rückgabeparameter von gibNullVec() ist am Stack (oder sonstwo) und bei der Zuweisung von vector wird der copy constructor aufgerufen. Solange also das was deine Funktion zurückgibt copy konstruiert werden kann (für alles in der stl der Fall) funktioniert das.

Sollte dies nicht korrekt sein, würde es dann korrekt sein, wenn ich die Funktion als inline definiere?

Danke schon einmal...

RLZ
2010-10-27, 22:35:50
Der Rückgabewert befindet sich vor der Rückgabe auf dem Stack (oder?).
Um die Sprache zu verstehen vergiss erstmal, dass du schonmal was von Stack und Heap gehört hast.

Deine Funktiondeklaration sagt, dass du das Objekt zurückgibst. Wo dieses Objekt angelegt wird oder ob der Wert kopiert werden muss, ist Sache des Compilers.

Anders sähe es aus, wenn du eine Referenz oder ein Pointer auf ein lokales Objekt zurückgeben würdest. Lokale Objekte werden nach Sprachdefinition nach Verlassen des Scopes zerstört und damit würde dein Rückgabewert auf ein ungültiges Objekt zeigen. Compiler warnen dich aber heutzutage davor.

P.S.:
Da in deinem Beispiel die Variable für den Compiler erkennbar referenziell transparent ist, wird von deiner Funktion nach der Optimierung nicht mehr viel übrig bleiben.

D4ve
2010-10-27, 23:28:37
Sollte dies nicht korrekt sein, würde es dann korrekt sein, wenn ich die Funktion als inline definiere?

Mit inline hat das nichts zu tun, da inline nur eine Empfehlung an den Compiler gibt, den Inhalt der Methode an die Stelle des Aufrufs zu setzen. Als Empfehlung kann es vom Compiler auch ignoriert werden, soweit ich weiß, kann der Compiler aber durchaus auch Methoden inlinen ohne dass das Schlüsselwort explizit gesetzt wurde.

Partner
2010-10-28, 00:45:00
Um die Sprache zu verstehen vergiss erstmal, dass du schonmal was von Stack und Heap gehört hast.Sorry, aber ich halte das für den größten Blödsinn überhaupt!

Wie soll man diverse Programmierkonzepte- und Beschränkungen effizient erlernen können wenn man deren Grund mangels Grundlagenkentnisse nicht kennt?


Beispiel:
"A: Warum wird ein Unterschied zwischen primitiven und komplexen Datentypen gemacht?
B: Das ist halt so. Lerne es einfach!"

Trap
2010-10-28, 09:06:48
Wie soll man diverse Programmierkonzepte- und Beschränkungen effizient erlernen können wenn man deren Grund mangels Grundlagenkentnisse nicht kennt?
Heap und Stack sind keine Konzepte von C++ (außer du meinst std::make_heap und std::stack). Die Unterscheidung von primitiven und komplexen Datentypen dagegen schon.

Heap und Stack ist in C++ ungefähr so wichtig wie das Paging des Betriebssystem, der Befehlssatz der CPU und der Aufbau des Cache. Alles kann einem in manchen Situationen helfen, aber zum Verständnis der Semantik ist es nie nötig.

Matrix316
2010-10-28, 10:23:00
Sorry, aber ich halte das für den größten Blödsinn überhaupt!

Wie soll man diverse Programmierkonzepte- und Beschränkungen effizient erlernen können wenn man deren Grund mangels Grundlagenkentnisse nicht kennt?

[...]

Weil Heap, Stack, Register und Zeug alles ein paar Ebenen tiefer liegen. Wenn du ein Spiel installierst, ist es dir ja auch egal, wie Direct X mit der Hardware kommuniziert oder so.

Wenn man Assembler programmiert, ist das wichtig. Bei C vielleicht je nach dem auch. Aber bei Objektorientierten Sprachen, gerade bei modernen, ist das eigentlich nicht wichtig.

Krishty
2010-10-28, 12:09:04
Wie Gast schon bemerkt hat, wird das Objekt per Kopierkonstruktor aus der Funktion zum Aufrufer kopiert. Gibt man keinen Kopierkonstruktor an und handelt es sich bei dem Objekt um ein sog. POD (Plain Old Data) -- also ein Objekt ohne private Attribute, ohne virtuelle Funktionen, ohne explizit programmierte Konstruktoren uvm -- erzeugt der Compiler diesen Kopierkonstruktor automatisch.

Anzumerken ist, dass der Compiler diese Kopie weglassen und das Objekt direkt beim Aufrufer erzeugen darf, wenn er möchte. Diese Return-Value-Optimization ist die einzige Optimierung in C++, die das Programmverhalten ändern darf (der Compiler darf also auch dann wegoptimieren, wenn der Kopierkonstruktor globale Wirkung hat).

Allerdings hat diese Optimierung Grenzen -- Visual C++ optimiert bspw nicht, wenn der Rückgabewert einen Destruktor hat ("unwindable" ist). Ist der Kopierkonstruktor also aufwändig und das Objekt unwindable -- z.B., wenn man hunderte MiB Bilddaten als Ergebnis des Ladens einer Bilddatei zurückgibt -- könnte das bemerkbare Nachteile haben und man sollte u.U. über Alternativen nachdenken.

C++0x erweitert die Optimierungsmöglichkeiten durch Move-Konstruktoren, durch die man in Fällen, in denen das zu kopierende Objekt eh sofort zerstört wurde, dessen Daten übernehmen statt kopieren kann.

Gruß, Ky

noid
2010-10-28, 12:50:15
Heap und Stack sind keine Konzepte von C++ (außer du meinst std::make_heap und std::stack). Die Unterscheidung von primitiven und komplexen Datentypen dagegen schon.

Heap und Stack ist in C++ ungefähr so wichtig wie das Paging des Betriebssystem, der Befehlssatz der CPU und der Aufbau des Cache. Alles kann einem in manchen Situationen helfen, aber zum Verständnis der Semantik ist es nie nötig.

Für den Anfang sollte er sich damit aber nicht beschäftigen. Siehe Mathematik, da werden viele Dinge implizit angenommen, definiert oder "verheimlicht". Erst wenn die GRundlagen stimmen sollte man die weiterführenden Dinge vermitteln.
(Siehe komplexe Zahlen... vs natürliche)

Zitronenbaum
2010-10-28, 14:11:53
Vielen Dank für die vielen Antworten. Sind mir ein wenig zu viel, um alles zu zitieren, ich versuch mal auf das wichtigste einzugehen.

Deine Funktiondeklaration sagt, dass du das Objekt zurückgibst. Wo dieses Objekt angelegt wird oder ob der Wert kopiert werden muss, ist Sache des Compilers.

Anders sähe es aus, wenn du eine Referenz oder ein Pointer auf ein lokales Objekt zurückgeben würdest. Lokale Objekte werden nach Sprachdefinition nach Verlassen des Scopes zerstört und damit würde dein Rückgabewert auf ein ungültiges Objekt zeigen. Compiler warnen dich aber heutzutage davor.

Dass ich Probleme bei der Referenzrückgabe von lokalen Objekten habe, war mir bekannt. Doch im Grunde ist der zurückgegebene vec2 auch lokal. Dass dieser in eine Zwischenablage kopiert wird, war mir so nicht bewusst. Ich ging irgendwie davon aus, dass es für solche Zwecke Register für Rückgabewerte gibt. Da Datentypen wie struct aber eine beliebige Größe haben können, war ich etwas verunsichert.

Wird im Beispiel der return-Wert direkt in Variable vector geschrieben oder an einer dritten Stelle zwischengelagert? Abseits von dem, was der Compiler an Optimierungen vornimmt. Würde ja Perfomance-mäßig einen Unterschied machen, besonders da ich teilweise größere Objekte habe.

Anzumerken ist, dass der Compiler diese Kopie weglassen und das Objekt direkt beim Aufrufer erzeugen darf, wenn er möchte. Diese Return-Value-Optimization ist die einzige Optimierung in C++, die das Programmverhalten ändern darf (der Compiler darf also auch dann wegoptimieren, wenn der Kopierkonstruktor globale Wirkung hat).

Beantwortet das meine Frage? Klingt irgendwie danach, wobei irgendwie...

Zur Heap Stack Diskussion: Ich würde mich damit schon gerne befassen. Einfach weil irgendwie in mir ein Bedürfnis danach besteht. Programmiere neben etwas in C, vielleicht erklärt es das. IMO ist der Bezug von C++ zu Dingen wie Heap und Stack ein Vorteil gegenüber anderen Sprachen. Abstraktion hin oder her, Hardwarenähe ist schon etwas feines. Sonst könnt ich ja gleich zu Java wechseln. Zumal dieses konkrete Beispiel durchaus beim Verständnis hilft, inwieweit eine Variable lokal oder beständig ist. Von Speicherlecks ganz zu schweigen...

Vielen Dank nochmal für die kompetenten Antworten. Bücher beantworten nicht immer unbedingt die Fragen, die man sich stellt.

Btw: Was ist dem Volksmund nach die Mutter der Porzellankiste?

Gast
2010-10-28, 15:08:02
Dass ich Probleme bei der Referenzrückgabe von lokalen Objekten habe, war mir bekannt. Doch im Grunde ist der zurückgegebene vec2 auch lokal. Dass dieser in eine Zwischenablage kopiert wird, war mir so nicht bewusst. Ich ging irgendwie davon aus, dass es für solche Zwecke Register für Rückgabewerte gibt. Da Datentypen wie struct aber eine beliebige Größe haben können, war ich etwas verunsichert.

Der vec2 ist lokal, ja, aber er wird bei der Zuweisung sofort copy konstruiert. Anders sieht es aus wenn du einen Pointer auf eine lokale Variable zurückgibst, dieser ist nach verlassen der Funktion ungültig da das Objekt auf das er zeigt (die lokale Variable) beim Verlassen des scope zerstört wird. Wenn du die Variable direkt zurückgibst wird sie wie oben gezeigt copy konstruiert.
Ob das ganze in Registern, am Stack, Heap oder sonstwo "zwischengespeichert" wird ist für deine Zwecke egal.

Wird im Beispiel der return-Wert direkt in Variable vector geschrieben oder an einer dritten Stelle zwischengelagert? Abseits von dem, was der Compiler an Optimierungen vornimmt. Würde ja Perfomance-mäßig einen Unterschied machen, besonders da ich teilweise größere Objekte habe.

In diesem Beispiel gibt es wie du erkannt hast einen gewissen Overhead weil das Objekt 2 mal exisitiert: Einmal als lokale Variable in der Funktion, und einmal außerhalb. Der copy konstruktor ist dafür zuständig die Daten zwischen diesen beiden Objekten zu "übertragen" (bildlich gesprochen). Das kann bei größeren Objekten durchaus Zeit kosten wie du ganz richtig erkannt hast. Die Alternative wäre dass du das Objekt innerhalb deiner Funktion nicht als lokale Variable ezuegst sondern dynamisch mit new anlegst und den Pointer darauf zurückgibst. Dann musst du dich aber auch um die Freigabe des Speichers explizit selber kümmern.

Beantwortet das meine Frage? Klingt irgendwie danach, wobei irgendwie...

Zur Heap Stack Diskussion: Ich würde mich damit schon gerne befassen. Einfach weil irgendwie in mir ein Bedürfnis danach besteht. Programmiere neben etwas in C, vielleicht erklärt es das. IMO ist der Bezug von C++ zu Dingen wie Heap und Stack ein Vorteil gegenüber anderen Sprachen. Abstraktion hin oder her, Hardwarenähe ist schon etwas feines. Sonst könnt ich ja gleich zu Java wechseln. Zumal dieses konkrete Beispiel durchaus beim Verständnis hilft, inwieweit eine Variable lokal oder beständig ist. Von Speicherlecks ganz zu schweigen...

Ganz einfach: Alles was nicht mit new angelegt wird ist eine lokale Variable und wird beim verlassen des scope zerstört.


Vielen Dank nochmal für die kompetenten Antworten. Bücher beantworten nicht immer unbedingt die Fragen, die man sich stellt.

Btw: Was ist dem Volksmund nach die Mutter der Porzellankiste?
Vorsicht

Partner
2010-10-28, 16:15:38
Heap und Stack sind keine Konzepte von C++ (außer du meinst std::make_heap und std::stack). Die Unterscheidung von primitiven und komplexen Datentypen dagegen schon.

Heap und Stack ist in C++ ungefähr so wichtig wie das Paging des Betriebssystem, der Befehlssatz der CPU und der Aufbau des Cache. Alles kann einem in manchen Situationen helfen, aber zum Verständnis der Semantik ist es nie nötig.Du gehst auf mein Argument nicht ein.
Jemand der einfach nur abstrakte Behauptungen lernt, ohne deren Begründung zu begreifen, lernt selbstverständlich schlechter als wenn er im Vorhinein die Grundlagen erlernt.

Man versteht nicht WARUM man zwischen primitiven und komplexen Datentypen unterscheidet wenn man nicht vorher das zugrundeliegende Speicherkonzept begriffen hat. Daher kann man nicht SELBSTSTÄNDIG herleiten WARUM man z.B. komplexen Datentypen als Funktionsrückgabetyp vermeiden sollte.

Man kann natürlich irgendwie die Grammatik der französischen Sprache erlernen, ohne deren Wortschatz zu kennen. Nur macht das Sinn?

Monger
2010-10-28, 17:11:47
Man versteht nicht WARUM man zwischen primitiven und komplexen Datentypen unterscheidet wenn man nicht vorher das zugrundeliegende Speicherkonzept begriffen hat.

Den Denkfehler den du hier machst, ist dass es einen kausalen Zusammenhang zwischen dem physikalischen Aufbau des Rechners und der Programmiersprache gibt. Das ist schlicht falsch: ein Bool kann - je nach Compiler - mal ein Bit, ein Byte oder ein Int verbrauchen. Manche Programmiersprachen kennen weder elementare Datentypen (z.B. .NET, ein Value type kann dort alles mögliche sein) noch Zeiger.
Ist ja auch nicht so, dass man in C++ genau weiß an welcher Stelle im Speicher man sich gerade befindet. Das Betriebssystem kann im Speichermanagement die Blöcke beliebig umsortieren, ohne dass du in deinem Programm irgendwas davon siehst. Kenntnisse vom Speicherkonzept des Betriebssystems sind eben KEINE Grundlage für deine Programmiersprache. Es ist schlicht ein völlig separates Themenfeld.


Daher kann man nicht SELBSTSTÄNDIG herleiten WARUM man z.B. komplexen Datentypen als Funktionsrückgabetyp vermeiden sollte.

Spätestens hier merkt man, dass du in deinem Denken sehr in C++ verhaftet bist. Die Empfehlung wäre in anderen Sprachen schlicht Bullshit. Call by Value/Reference existiert in anderen Sprachen in dieser Form ja gar nicht. In Java ist es völlig normal, große Objekte als Rückgabewert durch die Gegend zu reichen.

Partner
2010-10-28, 17:46:08
Den Denkfehler den du hier machst, ist dass es einen kausalen Zusammenhang zwischen dem physikalischen Aufbau des Rechners und der Programmiersprache gibt. Das ist schlicht falsch: ein Bool kann - je nach Compiler - mal ein Bit, ein Byte oder ein Int verbrauchen. Manche Programmiersprachen kennen weder elementare Datentypen (z.B. .NET, ein Value type kann dort alles mögliche sein) noch Zeiger.
Ist ja auch nicht so, dass man in C++ genau weiß an welcher Stelle im Speicher man sich gerade befindet. Das Betriebssystem kann im Speichermanagement die Blöcke beliebig umsortieren, ohne dass du in deinem Programm irgendwas davon siehst. Kenntnisse vom Speicherkonzept des Betriebssystems sind eben KEINE Grundlage für deine Programmiersprache. Es ist schlicht ein völlig separates Themenfeld.


Spätestens hier merkt man, dass du in deinem Denken sehr in C++ verhaftet bist. Die Empfehlung wäre in anderen Sprachen schlicht Bullshit. Call by Value/Reference existiert in anderen Sprachen in dieser Form ja gar nicht. In Java ist es völlig normal, große Objekte als Rückgabewert durch die Gegend zu reichen.Auch du ignorierst mein Argument vollkommen.

Es geht nicht darum ob eine Programmiersprache eine komplette Abstraktion des Rechners darstellt, sondern dass man den SINN/GRUND für die verschiedenen Konzepte einer Sprache nur dann versteht, wenn man auch die zugrunde liegenden Basis kennt, und somit viel effizienter lernt.

Klar kann ich das Wort "Kartoffel" erlernen ohne zu wissen was das eigentlich bedeutet. Nur ist das eben nicht sinnvoll!

Gnafoo
2010-10-28, 17:55:12
In diesem Beispiel gibt es wie du erkannt hast einen gewissen Overhead weil das Objekt 2 mal exisitiert: Einmal als lokale Variable in der Funktion, und einmal außerhalb. Der copy konstruktor ist dafür zuständig die Daten zwischen diesen beiden Objekten zu "übertragen" (bildlich gesprochen). Das kann bei größeren Objekten durchaus Zeit kosten wie du ganz richtig erkannt hast. Die Alternative wäre dass du das Objekt innerhalb deiner Funktion nicht als lokale Variable ezuegst sondern dynamisch mit new anlegst und den Pointer darauf zurückgibst. Dann musst du dich aber auch um die Freigabe des Speichers explizit selber kümmern.

Wobei man dabei beachten muss, dass „new“ auch einen Overhead mit sich bringt (die Allokation an sich kostet und die Cache-Effizienz ist kleiner). Außerdem ist es – wie gesagt – wegen dem delete fehleranfälliger. Für eine kleine Struktur wie in dem Beispiel würde sich das gar nicht lohnen, weil eine Kopie dort viel günstiger ist, als die Allokation mit „new“. Mit etwas Glück wird sie sowieso wegoptimiert. Rückgabe per Kopie kann daher durchaus legitim sein und ist imho nicht selten vorzuziehen. Gewissheit über die Laufzeit schafft ein Profiler. Objekte ohne saubere Kopier-Semantik sollten Copy-Konstruktor und Zuweisungs-Operator verstecken (siehe z. B. boost::noncopyable).

Wenn man wirklich große Objekte hat, bei denen eine Kopie teuer ist, bietet sich evtl. auch ein Smart-Pointer an, um der delete-Problematik zu entgehen. Oder man übergibt der Funktion ein Objekt per Referenz und ändert es dort, anstatt ein neues zu erzeugen und zurückzugeben. Bietet sich z. B. bei Containern wie std::vector an.

Gast
2010-10-28, 17:57:25
Spätestens hier merkt man, dass du in deinem Denken sehr in C++ verhaftet bist. Die Empfehlung wäre in anderen Sprachen schlicht Bullshit. Call by Value/Reference existiert in anderen Sprachen in dieser Form ja gar nicht. In Java ist es völlig normal, große Objekte als Rückgabewert durch die Gegend zu reichen.
Wie kann bei Java eine Empfehlung für etwas, was in Java nicht existiert, Bullshit sein?

Monger
2010-10-28, 18:17:45
Auch du ignorierst mein Argument vollkommen.

Es geht nicht darum ob eine Programmiersprache eine komplette Abstraktion des Rechners darstellt, sondern dass man den SINN/GRUND für die verschiedenen Konzepte einer Sprache nur dann versteht, wenn man auch die zugrunde liegenden Basis kennt, und somit viel effizienter lernt.

Klar kann ich das Wort "Kartoffel" erlernen ohne zu wissen was das eigentlich bedeutet. Nur ist das eben nicht sinnvoll!
Dann erklär doch mal die Etymologie des Wortes "Kartoffel".

Eine Sprache ist immer historisch gewachsen, das gilt genauso für Deutsch wie für Python. Alles davon hatte mal seinen Grund, aber kaum einer kennt ihn. C++ ist z.B. sehr deutlich die Verwandtschaft zu C anzusehen, und wo man ja gerne mal Microcontroller direkt programmiert. Wer so nahe an der Hardware arbeitet, möchte sich auch da in der Programmiersprache wiederfinden. Aber einen konkreten Grund, warum C++ jetzt die einen Objekte auf diesem Stack ablegt, und andere woanders könnte zumindest ich nicht nennen. Das ist nicht alles ganz rational.

Partner
2010-10-28, 18:41:04
Dann erklär doch mal die Etymologie des Wortes "Kartoffel".

Eine Sprache ist immer historisch gewachsen, das gilt genauso für Deutsch wie für Python. Alles davon hatte mal seinen Grund, aber kaum einer kennt ihn. C++ ist z.B. sehr deutlich die Verwandtschaft zu C anzusehen, und wo man ja gerne mal Microcontroller direkt programmiert. Wer so nahe an der Hardware arbeitet, möchte sich auch da in der Programmiersprache wiederfinden. Aber einen konkreten Grund, warum C++ jetzt die einen Objekte auf diesem Stack ablegt, und andere woanders könnte zumindest ich nicht nennen. Das ist nicht alles ganz rational.Dann sollte man Softwareentwicklung gleich sein lassen oder wie?

Es gibt einen sehr einfach zu begreifenden Grund für das Beispiel der Unterscheidung zwischen primitiver/komplexer Datentypen.
Versteht man das darunterliegende Speicherkonzept, kann man auch diese Unterscheidung und all die daraus resultierenden Konzepte im Beispiel CPP nachvollziehen und ableiten.

Über solche eindeutigen Verständnisse zu diskutieren wird mir jetzt echt zu blöd.

Coda
2010-10-28, 18:43:10
Wer elementare Grundkenntnisse nicht versteht wird auch in einer managed Sprache schlechter programmieren, da stimm ich aus Erfahrung Partner absolut zu.

In welcher Reihenfolge man sich das Wissen aneignet (zuerst die Abstraktion und dann die Grundlagen oder andersherum) halte ich aber für ziemlich irrelevant. Das soll jeder so machen wie er mehr Spaß an der Sache hat.

Man darf nur nicht in diese "brauch ich eh nicht"-Arroganz verfallen. Und das gilt in beide Richtungen. Ich kenne genug C-Programmierer die Java nicht anfassen würde und vice verca. Völlig bekloppt.

Trap
2010-10-28, 19:38:21
Es geht nicht darum ob eine Programmiersprache eine komplette Abstraktion des Rechners darstellt, sondern dass man den SINN/GRUND für die verschiedenen Konzepte einer Sprache nur dann versteht, wenn man auch die zugrunde liegenden Basis kennt, und somit viel effizienter lernt.
Die Unterscheidung zwischen new-allozierten Objekten und "normalen" Objekten an der Implementierung der Funktionalität festzumachen ist meiner Meinung nach keine sonderlich erhellende Sichtweise. Sie erklärt zwar das Verhalten beider Varianten, aber nicht wozu man sie nutzen sollte.

Edit: Eigentlich erklärt sie das Verhalten auch nur für PODs.