[C++] Simples aber merkwürdiges Problem

p4z1f1st

Grand Admiral Special
Mitglied seit
28.04.2003
Beiträge
9.722
Renomée
81
Hi!

Ich darf nun in meinem Studium in den Genuß einer C++Vorlesung kommen und muss mich daher mit dem Blödsinn rumschlagen ^^

Jetzt sollen wir ne ganz einfache Aufgabe bewerkstelligen, die an sich net wirklich schwer ist:
Es soll einfach die Funktion cos(x) einmal in Bogenmaß und einmal in Grad angegeben werden (in 30° bzw. 1/6-pi Schritten), wobei man vorher wählen sollen kann, welches man ausgegeben haben will.

Gesagt getan, einfach ne For-schleife für die Abzählung der einzelnen 30er-Schritte (bzw. 1/6-pi Schritte) gebaut und davor dann eine noch einfacherere if-Schleife reingeschustert.

Jetzt ist mein Problem, dass er meine if-schleife nicht will, obwohl jene aus einer Variablen und insgesamt genau 2 Zeilen besteht:

(if (ausdruck1)
anweisung1
else
answeisung2

mein Visual C++ sagt mir im genauen Wortlaut "error C2181: Ungültiges 'else' ohne zugehöriges 'if'"

Hier mal mein Code:

Code:
#include <stdafx.h>
#include <stdio.h>
#include <math.h>
#define _USE_MATH_DEFINES
#define M_PI 3.141592654
#include <iostream>
using namespace std;

int main (void)
{
	float d=0;
	float e=M_PI/6;
	int x;
	int y=0;
	int z=0;

	printf("Fuer Bogenmass bitte '0' eingeben. Sonst Ausgabe in Grad.\n");
	cin >> y;
	if (y > 0)
		printf("Ausgabe von Cos(x) in Grad\n");
		for (x=0 ; x<=12 ; x++)							// For-Schleife (solange x <= 12, Schleife ausführen)
		{
			printf("%d\n",z);
			z=z+30;										// z um 30° erhöhen
		}
	else
		printf("Ausgabe von Cos(x) im Bogenmass\n");
		for (x=0 ; x<=12 ; x++)
		{
			printf("%f\n",d);
			d=d+e;
		}


return 0;
}

Erstmal das und dann noch eine "Schönheitskorrekturfrage". Und zwar arbeiten wir z.Zt. ausschließlich mit <stdio.h>, statt mit dem mir von der Oberstufe bekannten <iostream> samt "using namespace std;" - Aber ich komme mit dem Befehl "scanf" nicht ganz klar und hab daher aufs altbewerte "cin >>" gegriffen.
Könnt mir einer das mal bissl anschaulich für mein Beispiel erklären? (Dann müsste ich auch net die iostream-bibliothek einfügen und es wäre einheitlicher, was mein Prof vermutlich haben will)

MfG p4z1
 
du hast die { } vergessen bei IF und ELSE

Korrekte Syntax:

IF (...)
{
...
}
ELSE
{
}

Weglassen darfst du diese nur, wenn die Anweisung aus maximal einer Zeile besteht
.
EDIT :
.

scanf:

http://www.cplusplus.com/reference/clibrary/cstdio/scanf.html

Somit solltest du folgendes verwenden:
scanf ("%d",&i);

und natürlich noch bei sämtlichen Funktionsaufrufen darauf achten, Fehler abzufangen ( wollten zumindest meine Profs immer sehen.. ).
 
oh danke vielmals!

geht nun auch mit scanf() :)
 
So sehe das Ganze in C++ aus:
Code:
#include <cmath>
#include <iostream>
#include <sstream>
using namespace std;

const float PI = 3.141592654f;

int main()
{
	const float e = PI/6.0f;

	cout << "Für Bogenmass bitte '0' eingeben. Sonst Ausgabe in Grad.\n";
	int user_input;
	cin >> user_input;

	stringstream ss;
	ss << user_input;

	int user_choice;
	ss >> user_choice;

	if ( ss.fail() || user_choice  != 0 )
	{
		cout << "Ausgabe von Cos(x) in Grad\n";
		float current = 0;

		for ( int i = 0; i <= 12; ++i )							
		{
			cout << cos(current) << "\n";
			current += 30.0f;										
		}
	}
	else
	{
		cout << "Ausgabe von Cos(x) im Bogenmass\n";
		float current = 0;

		for ( int i = 0; i <= 12; ++i )
		{
			cout << cos(current) << "\n";
			current += e;
		}
	}

	return 0;
}

Das "using namespace std;" sollte möglichst auch vermieden werden, das "Entblößen" eines ganzen Namespaces generell spricht etwas gegen die Idee dahinter, besonders wenn man es mit solch großen Varianten macht. Stattdessen sollte man sich die Zeit nehmen und wirklich jedes mal die mit Hilfe des Scope-Operators ( :: ) die jeweilige Funktionalität heraussuchen. Alternativ für Schreibfaule gibt es den Zwischenweg mit "using std::cout;" ect. für häufig genutze Sachen.

Ich bin sehr darüber überrascht, dass ihr ausschließlich mit stdio.h arbeitet, eine C Bibliothek in einem C++ Kurs.
C++ hat eigentlich gar keine .h Endungen bei Headerdateien und auch Funktionen wie printf oder scanf sind reine C Funktionen und haben in einem frisch aufgelegten C++ Programm nichts zu suchen. Mir fällt auch die Initialisierung der lokalen Variablen jeweils am Anfang einer Scope auf, typisch für C Code und gilt als schlechter Stil für C++ Programme.
Vielleicht sollte euer Professor korrekterweise den Kurs einfach in C - Kurs umbennen. ???
 
Zuletzt bearbeitet:
also ich würde das Programm auch neu aufsetzen
das ist bis auf cin und Kleinigkeiten alles Ansi-C

was lernt ihr also wirklich?
C oder C++ ?

auch mal so aus Neugier
welchen Compiler benutzt ihr?
ich habe z.B. festgestellt, das math.h bei mir zu Hause mit gcc M_PI definiert hat, Visual Studio (wird so vom Prof und uns verlangt) aber nicht
bei C++ bin ich noch nicht ganz so weit
Mir fällt auch die Initialisierung der lokalen Variablen jeweils am Anfang einer Scope auf, typisch für C Code und gilt als schlechter Stil für C++ Programme.
das mache ich aber auch so bzw. damit hatte ich auch schon Probleme
bei uns liegt es allerdings daran, das wir 1,5 Semester Ansi C programmiert haben und jetzt auf objektorientierte Programmierung für ein halbes Semester übergehen
da benutzt man einiges erstmal weiter, vorallem wenn man mehr oder weniger selbst alles suchen muß
das Schlimme ist nur, das es bei unseren simplen Programmen gut geht

MfG Micha
 
Das Initialisieren der Variablen jeweils am Anfang ist meines Wissens auch nicht so schlimm (gerade für Optimierungen hat das bei modernen Kompiler kaum Auswirkungen, die sind mittlerweile clever genug), soll nur Zwecks Übersicht anders geregelt werden, was für Einige die gegenteilige Wirkung zu haben scheint.

Es könnte jedoch ein weiterer Hinweis darauf sein, dass da eigentlich C gelehrt wird.
Gerade in den For-Schleifen sieht es auffällig aus, da soweit ich mich erinnern kann in C die Initialisierung des schleifen-lokalen Zählers innerhalb des Schleifenkopfes nicht gültig ist, aber bei C++ standardmäßig praktiziert wird.
 
Zuletzt bearbeitet:
Das "using namespace std;" sollte möglichst auch vermieden werden, das "Entblößen" eines ganzen Namespaces generell spricht etwas gegen die Idee dahinter, besonders wenn man es mit solch großen Varianten macht. Stattdessen sollte man sich die Zeit nehmen und wirklich jedes mal die mit Hilfe des Scope-Operators ( :: ) die jeweilige Funktionalität heraussuchen. Alternativ für Schreibfaule gibt es den Zwischenweg mit "using std::cout;" ect. für häufig genutze Sachen.
kannst du mal bitte ganz kurz schreiben wie "Hello World" damit aussieht?
also ohne "using namespace std"
man findet bei den ersten paar Google Treffern nur mit
wir benutzen das zur Zeit auch noch (sicher um uns bei der ersten Aufgabe in C++ nicht total zu verwirren)


Das Initialisieren der Variablen jeweils am Anfang ist meines Wissens auch nicht so schlimm (gerade für Optimierungen hat das bei modernen Kompiler kaum Auswirkungen, die sind mittlerweile clever genug), soll nur Zwecks Übersicht anders geregelt werden, was für Einige die gegenteilige Wirkung zu haben scheint.
ich meine das auch nicht für die Variablen, sondern allgemein
in der jetzigen Aufgabe habe ich auch erstmal math.h weiterverwendet, war Wurzel oder so gefordert und das die in C++ cmath habe ich halt erst später mitbekommen usw.

Es könnte jedoch ein weiterer Hinweis darauf sein, dass da eigentlich C gelehrt wird.
ich gehe mal stark davon aus
das was du geschrieben hast sieht für mich noch wegen den "cout<<" etwas "unbekannt" aus, aber das was p4z1f1st geschrieben hat, ist mir sehr vertraut
Gerade in den For-Schleifen sieht es auffällig aus, da soweit ich mich erinnern kann in C die Initialisierung des schleifen-lokalen Zählers innerhalb des Schleifenkopfes nicht gültig ist, aber bei C++ standardmäßig praktiziert wird.
ganz, ganz früher hatte ich java und auch wenn ich davon nichts mehr wußte, die for-Schleifen haben anfangs bei mir nicht funktionieren wollen
nur jetzt im 2. Semester mit C kann ich nicht mehr anders und initialisiere auch bei C++ gleich *buck*

MfG Micha
 
ein Tipp zur Übersicht würde ich die Variablendeklaration immer am anfang der main Funktion vornehmen
das erleichtert anderen deinen Code zu lesen
ich frage mich auch was es füreinen sinn hat die eingabe über die Variable user_input aber in der if Anweisung die variable user_choice zu benutzen
der inhalt beider müsste doch gleich seinn oder etwa nicht?
die Addition der Variablen "current" kann auch in im schleifenkopf vorgenommen werden was die Lesbarkit eigentlich auch verbessern sollte.
achja das f hinter den werten der float variablen kannst du auch weglassen

das ganze würde dann so aussehen
Code:
#include <cmath>
#include <iostream>
#include <sstream>
using namespace std;

const float PI = 3.141592654;

int main()
{
	const float e=PI/6.0;
	int	user_input;
	float current=0;
	stringstream ss;

	cout << "Für Bogenmass bitte '0' eingeben. Sonst Ausgabe in Grad.\n";	
	cin >> user_input;
	ss << user_input;

	if(ss.fail() || user_input!=0)
	{
		cout << "Ausgabe von Cos(x) in Grad\n";
		for(int i=0; i<=12; ++i,current+=30)							
		{
			cout << cos(current) << "\n";									
		}
	}
	else
	{
		cout << "Ausgabe von Cos(x) im Bogenmass\n";
		for(int i=0; i<=12; ++i, current+=e)
		{
			cout << cos(current) << "\n";
		}
	}

	return 0;
}
 
Zuletzt bearbeitet:
ein Tipp zur Übersicht würde ich die Variablendeklaration immer am anfang der main Funktion vornehmen
Jo, so hat man das vor 15 Jahren gemacht ;)

Der Sinn der Definition "on the fly" ist, dass eine Variable erst definiert wird, wenn sie auch benötigt wird. Es kann sein, dass das Programm vorher anders verzweigt und die ganze Definition sinnlos war. Selbst, wenn nicht gleichzeitig noch eine aufwändige Initialisierung der Variable stattfindet und man somit den Laufzeitvorteil vernachlässigen kann, so erhöht sich doch die Lesbarkeit.

Migmicha hat die Frage gestellt, wie denn "Hello world" ohne "using namespace std" aussieht, na etwa so:
std::cout << "Hello World" << std::endl;
 
Ok, nach eMail-Abfrage des Profs, lernen wir doch "nur" rein C - wir benutzen nur Visual C++ als Kompiler.
 
Jo, so hat man das vor 15 Jahren gemacht ;)

Der Sinn der Definition "on the fly" ist, dass eine Variable erst definiert wird, wenn sie auch benötigt wird. Es kann sein, dass das Programm vorher anders verzweigt und die ganze Definition sinnlos war. Selbst, wenn nicht gleichzeitig noch eine aufwändige Initialisierung der Variable stattfindet und man somit den Laufzeitvorteil vernachlässigen kann, so erhöht sich doch die Lesbarkeit.

Migmicha hat die Frage gestellt, wie denn "Hello world" ohne "using namespace std" aussieht, na etwa so:
std::cout << "Hello World" << std::endl;
wenn verzweigungen dazukommen gut dann muss ich dir zustimmmen aber wenn wie bei diesem Programm alle Variablen auch wirklich genutz werden welchen performance vorteil soll es dann bringen die Variablen "on the fly" zu deklarieren? :]
nach meinem empfinden erhöht es auch nicht die lesbarkeit der Codes wenn man wie eamC die variable ss erst vor der eingabe deklariert.
 
insbesondere bei for-Schleifen erhöht das den Komfort
bei C schreibt man die Schleife und muß erstmal an den Anfang des Unterprogramms um eine neue Variable zu deklarieren
bei C++ und Java schreibt man einfach for(int i=0;...;...)
die Variable ist auch nur innerhalb der Schleife gültig
damit kann man sie danach nochmal neu deklarieren bzw. eine vorher schon verwendete Variable bleibt erhalten
die in der Schleife ist eine andere Variable

um das zu verdeutlichen, was ich meine:
Code:
#include <iostream>

int main() {
	int i=1;
	
	for(int i=0;i<=5;i++)
		 std::cout << " Wert in der Schleife  i= "<< i << std::endl;
	
	std::cout << " Wert ausserhalb i= "<< i << std::endl;
	

	std::cout <<"\n"<<std::endl;
return 0;
}
Wert in der Schleife i= 0
Wert in der Schleife i= 1
Wert in der Schleife i= 2
Wert in der Schleife i= 3
Wert in der Schleife i= 4
Wert in der Schleife i= 5
Wert ausserhalb i= 1

bei C geht das nicht
um das selbe zu erreichen müßte man zwei Variablen definieren, eine für die Schleife und eine Außerhalb

@Nachtschicht
danke, ergibt langsam einen Sinn für mich

MfG Micha
 
Zuletzt bearbeitet:
klar geht das bei C
zumindest unte rLinux mit gcc als Compiler gibt es da keine Probleme

das man die Zählvariablen der Schleife im Schleifenkopf deklariert und zuweisst ist aber auch nichts aussergewöhnliches und dem habe ich auch nicht wiedersprochen
 
Code:
#include <stdio.h>

int main(){

	int i=1;  // im zweiten Versuch auskommentiert
	
	for(int i=0;i<=5;i++)
		printf("innen: %d \n",i);
	
	printf("aussen: %d \n",i);

//	getchar();
	printf("\n\n");
	return 0;
}

gcc Hallo.c
Hallo.c: In function ‘main’:
Hallo.c:8: error: redefinition of ‘i’
Hallo.c:6: error: previous definition of ‘i’ was here
Hallo.c:8: error: ‘for’ loop initial declaration used outside C99 mode

gcc4.1 Ubuntu Edgy Eft

wäre auch nicht nach Ansi C korrekt, wenn es doch funktioniert hätte

selbst wenn man die erste Initialisierung weglässt
gcc Hallo.c
Hallo.c: In function ‘main’:
Hallo.c:5: error: ‘for’ loop initial declaration used outside C99 mode

Ok, nach eMail-Abfrage des Profs, lernen wir doch "nur" rein C - wir benutzen nur Visual C++ als Kompiler.
wir benutzen wie gesagt auch Visual Studio
da muß man die Quelltexte immer unter *.c abspeichern und schon wird der interne C-Kompiler verwendet
wenn man die Dateien einfach nur mit dem Namen speichert, wird eine *.cpp daraus und beim Kompilieren erhält man 100 Fehlermeldungen *buck*
bei deinem Programm hast du noch Glück...

MfG Micha
 
ein Tipp zur Übersicht würde ich die Variablendeklaration immer am anfang der main Funktion vornehmen
das erleichtert anderen deinen Code zu lesen
ich frage mich auch was es füreinen sinn hat die eingabe über die Variable user_input aber in der if Anweisung die variable user_choice zu benutzen
der inhalt beider müsste doch gleich seinn oder etwa nicht?
die Addition der Variablen "current" kann auch in im schleifenkopf vorgenommen werden was die Lesbarkit eigentlich auch verbessern sollte.
achja das f hinter den werten der float variablen kannst du auch weglassen

das ganze würde dann so aussehen
Wie schon von anderen erwähnt wird wegen Optimierungszwecken (mittlerweile zweitrangig) und der Übersicht wegen gerade das nicht gemacht.

Die Variable user_choice habe ich ebenfalls fürs Verständnis eingefügt, man hätte von Stringstream zurück in user_input streamen können, hätte die gleiche Wirkung gehabt.
Das Stringstream ist in diesem Fall eigentlich ganz überflüssig, sollte man sich aber vormerken für spätere Programme, welche die Eingabe auch auf Korrektheit überprüfen sollen.

Das current kann man in den Schleifenkopf stellen, ist denke ich wie bei den Variablendeklerationen Geschmacksache was übersichtlicher wirkt. Ich persönlich habe mir angewöhnt im Schleifenkopf nur die Variablen zu bearbeiten, auf die auch in diesem geprüft wird.

Das f könnte man weglassen, sollte man aber nicht. Eine x.x Zahl wird vom Compiler immer als double interpretiert, dies kann in manchen Fällen zu unerwünschten automatischen Castingvorgängen führen, die vor einem selbst unerkannt bleiben aber besonders in engen Schleifen zu Performanceeinbüßen führen können.
 
Zuletzt bearbeitet:
Wie schon von anderen erwähnt wird wegen Optimierungszwecken (mittlerweile zweitrangig)
Na, da habe ich so meine Zweifel, ob das in Bezug auf die Performance zweitrangig ist, an welcher Stelle Variablen definiert werden. Bei einem single-threaded-Programm kann ich mir noch vorstellen, dass ein Compiler eine Variable wirklich erst initialisiert, wenn sie auch benötigt wird. So richtig spannend wird es bei Multithreaded Programmen. Den Compiler möchte ich sehen, der da an all Eventualitäten "denkt" und das Ganze fehlerfrei behandelt. Zumal ja erst der Linker weiß, ob der ganze Krempel ST oder MT ist. ;)

Gibt es dazu Links?

Ein weiterer Aspekt, der für die Definition "on the fly" spricht, ist, dass man möglichst gleich den richtigen Konstruktor aufrufen sollte, dessen Initialisierungswerte womöglich nicht gleich zu Beginn der Methode zu Verfügung stehen, z.B.:

std::string abc; //Konstruktor
abc = "bodo"; //Zuweisungsoperator
ist langsamer als
std::string abc ("bodo"); // nur Konstruktor
 
Ein weiterer Aspekt, der für die Definition "on the fly" spricht, ist, dass man möglichst gleich den richtigen Konstruktor aufrufen sollte, dessen Initialisierungswerte womöglich nicht gleich zu Beginn der Methode zu Verfügung stehen, z.B.:

std::string abc; //Konstruktor
abc = "bodo"; //Zuweisungsoperator
ist langsamer als
std::string abc ("bodo"); // nur Konstruktor
Ein sehr gutes Beispiel.
Man sieht oft solche Konstruktionen wie "string s = "mein Text";" und auch in diesem Fall würde das Programm zuerst ein String s erzeugen, dann ein weiteres String und dann in diesem besonderen Fall den Copy-Konstruktor aufrufen um den Text s zuzuweisen.
Ähnlich vorgehen sollte man auch wenn man Objekte zurückgeben möchte.

Z.B. "return meinObjekt(meinArgument);"
statt
" meinObjekt x(meinArgument);
return x;".
 
Zuletzt bearbeitet:
Ähnlich vorgehen sollte man auch wenn man Objekte zurückgeben möchte.

Z.B. "return meinObjekt(meinArgument);"
statt
" meinObjekt x(meinArgument);
return x;".
Das ist nun in Bezug auf die Performance wirklich nahezu egal, ob der Speicherbereich, der niemandem gehört oder der Speicherbereich der Variable x zurückgegeben wird. Das sage ich als alter Assemblerprogrammierer ;) In den Firmen gibt es mitunter sogar Coding-Guidelines, die genau diese elegante Methode des "returns" untersagen.

Ich würde oft die umständlichere Variante wählen, denn der Tag wird kommen, an dem man genau an der Stelle mit dem Debugger einen Fehler suchen wird und man wird dankbar sein für jede nicht wegoptimierte Zeile umständlichen Codes ;)
 
Das ist nun in Bezug auf die Performance wirklich nahezu egal, ob der Speicherbereich, der niemandem gehört oder der Speicherbereich der Variable x zurückgegeben wird. Das sage ich als alter Assemblerprogrammierer ;) In den Firmen gibt es mitunter sogar Coding-Guidelines, die genau diese elegante Methode des "returns" untersagen.

Ich würde oft die umständlichere Variante wählen, denn der Tag wird kommen, an dem man genau an der Stelle mit dem Debugger einen Fehler suchen wird und man wird dankbar sein für jede nicht wegoptimierte Zeile umständlichen Codes ;)
Nun, nach dem Ende der Scope ist der Speicherbereich in beiden Fällen herrenlos.
Zwar bin ich kein erfahrener Assemblerprogrammierer, aber als C++ Programmierer sage ich Dir es ist nicht egal in Bezug auf Performance.
Der Begriff "Return-Value Optimization" wurde meines Wissens von Scott Meyers in dem Standardwerk "Effective C++" ans Licht geführt und verdeutlicht welche Optimierungsmöglichkeiten man hat, wenn man Objekte by Value zurückzugeben hat.
Bruce Eckel hat dieses auch in einem weiteren wichtigen C++ Buch aufgegriffen, in "Thinking in C++", somit befinde ich mich auf der sicheren Seite dies zu behaupten 8) .

Kurz gesagt spart man sich einen Konstruktor- und Dekonstruktoraufruf, wenn man den Aufruf direkt beim Return-Statement durchführt, was bei komplexen Objekten immense Geschwindigkeitsvorteile hat.
In vielen Fällen wird der Compiler selbst so eine Funktion umbauen, indem er den Return-Wert als Referenz übergibt, Dein lokales Objekt somit unnötig macht und entfernt.
Diese Arbeit sollte man jedoch selbst übernehmen, das gehört einfach zum guten Ton.

Welche Firmen sich gegen Größen wie Scott Meyers gegenstellen was C++ Programmierung angeht interessiert mich aber nun sehr ;D .
Womögliche arbeiten diese Firmen nicht an performancekritischer Software, das wäre eine logische Erklärung?
 
Kurz gesagt spart man sich einen Konstruktor- und Dekonstruktoraufruf, wenn man den Aufruf direkt beim Return-Statement durchführt, was bei komplexen Objekten immense Geschwindigkeitsvorteile hat.
Das verstehe ich gerade nicht, wieso wird der Konstruktor- und Destruktoraufruf eingespart, wenn man das Objekt nur auf dem Stack erzeugt und zerstört? *noahnung*

Welche Firmen sich gegen Größen wie Scott Meyers gegenstellen was C++ Programmierung angeht interessiert mich aber nun sehr ;D .
Womögliche arbeiten diese Firmen nicht an performancekritischer Software, das wäre eine logische Erklärung?
Naja, Scotti muß auch seine Bücher verkaufen ;D Ein paar Kollegen hatten einen Kurs bei ihm gewonnen, aber auf die einfache Frage, ob denn seines Wissens C++ in einer sicherheitskritischen Applikation eingesetzt wird (an der Menschenleben hängen), wußte er keine Antwort bzw. konnte kein Beispiel nennen. *suspect* (Die Alternative ist C, was auch benutzt wird).

In der Praxis sind Zuverlässigkeit, Reproduzierbarkeit, etc. allemal wichtiger als minimale Performancevorteile in womöglich völlig unwichtigen Codeteilen, die selten durchlaufen werden.
 
"return meinObjekt(meinArgument);"
statt
" meinObjekt x(meinArgument);
return x;".

solange man keine Debug-builds an Kunden ausliefert, sind beide Versionen gleich schnell (RVO)

std::string abc; //Konstruktor
abc = "bodo"; //Zuweisungsoperator
ist langsamer als
std::string abc ("bodo"); // nur Konstruktor
aber nur weil die Implementierung von std::string() nicht trivial ist. Sonst wird das auch wegoptimiert.
 
Das verstehe ich gerade nicht, wieso wird der Konstruktor- und Destruktoraufruf eingespart, wenn man das Objekt nur auf dem Stack erzeugt und zerstört? *noahnung*
Das war mir Anfangs auch nicht klar. Meine Folgerung aus der Compileroptimierung war, dass das Return Objekt so bereits die Referenz ist des Objektes welches das Return Statement erwartet, also in etwa so:
Code:
MyClass myObject = getMyObject();
...
MyClass getMyObject() 
{
    MyClass tempObject;
    return tempObject;
}

Wird vom Compiler in Folgendes optimiert:
Code:
void getMyObject( MyClass& _returnRef )
{
    _returnRef = MyClass();
    return;
}

Somit fällt der Konstruktor- und Dekonstruktoraufruf von tempObject aus.
Mit dem Umschreiben in return MyClass(); kommt man ledeglich dem Compiler entgegen dh. das Return Statement wird direkt in den Assigment Parameter genommen.

In der Praxis sind Zuverlässigkeit, Reproduzierbarkeit, etc. allemal wichtiger als minimale Performancevorteile in womöglich völlig unwichtigen Codeteilen, die selten durchlaufen werden.
Stimme Dir da natürlich zu, jedoch bleibt die Aussage korrekt, dass es Performancevorteile dadurch gibt, und in diesem Fall verliert man kaum an Leserlichkeit oder Stabilität. Was das Debuggen angeht, das Return Objekt wird ja dem erwartenden Objekt gleichgesetzt, deswegen verstehe ich nicht ganz den Nachteil wenn man es so schreibt.
 
Zuletzt bearbeitet:
Zurück
Oben Unten