• Liebe User, bitte beachtet folgendes Thema: Was im Forum passiert, bleibt im Forum! Danke!
  • Hallo Gemeinde! Das Problem leidet zurzeit unter technischen Problemen. Wir sind da dran, aber das Zeitkontingent ist begrenzt. In der Zwischenzeit dürfte den meisten aufgefallen sein, dass das Erstellen von Posts funktioniert, auch wenn das Forum erstmal eine Fehlermeldung wirft. Um unseren Löschaufwand zu minimieren, bitten wir euch darum, nicht mehrmals auf 'Post Reply' zu klicken, da das zur Mehrfachposts führt. Grußworte.

Frage an die C++ Profis

Mitglied seit
04.08.2002
Beiträge
1.869
Reaktionen
0
Hab hier gerade nen kleines Test-Programm von nem Arbeitskollegen bekommen und wir rätseln über die Ausgabe.

Zunächst mal das Programm:

Code:
#include <cstdio>
#include <cstdlib>
#include <cstring>

class XYZ
{
	private:
		int n;

	public:

	XYZ()
	{
		n = 5;
		printf("Constructor: %d\n", n);
	}

	~XYZ()
	{
		printf("Destructor: %d\n", n);
	}

	void set(int n)
	{
		this->n = n;
	}

	int get()
	{
		return n;
	}
};

void f();
XYZ g();

int main()
{
	printf("BEFORE f()\n");
	f();
	printf("AFTER f()\n");
	return(0);
}

void f()
{
	printf("BEFORE g()\n");
	XYZ result = g();
	printf("AFTER g()\n");
	printf("Result: %d\n", result.get());
}

XYZ g()
{
	printf("BEFORE creation\n");
	XYZ x;
	printf("AFTER creation\n");
	x.set(11);
	printf("Changed value to: %d\n", x.get());
	return(x);
}


Die Ausgabe ist folgende:

BEFORE f()
BEFORE g()
BEFORE creation
Constructor: 5
AFTER creation
Changed value to: 11
AFTER g()
Result: 11
Destructor: 11
AFTER f()

Das ganze wurde auf Solaris mit dem SUN Workshop Compiler gebaut.

Ich hätte erwartet, dass VOR der Ausgabe von "AFTER g()" einmal der Destuktor für das Objekt x aufgerufen wird, welches innerhalb der Methode g() auf dem Stack angelegt wird. Dies ist aber scheinbar nicht der Fall. Zu Hülf mit einer guten Erklärung!

thx,
M
 
Mitglied seit
01.01.1970
Beiträge
1.170
Reaktionen
0
wegen "XYZ result = g();"
wenn du willst, dass das objekt in der funktion g() am ende terminieren soll, müsstest du den =operator selbst überladen.
ansonsten kopiert der nur die referenz und initialisiert kein zweites objekt.

bzw.
versuch mal
XYZ result;
result = g();

da müsste die ausgabe dann anders sein.
 
Zuletzt bearbeitet:
Mitglied seit
15.09.2000
Beiträge
1.766
Reaktionen
418
Ich find das gerade spannend und habs gerade getestet (g++ auf ubuntu).

1. Die Ausgabe war bei mir gleich.

2.
XYZ result;
result = g();
bringt das erwartete Ergebnis, also er erzeugt und zerstoert das temporaere Objekt.

3.
Operator= zu overloaden aendert nichts, der operator= wird gar nicht gecalled.


Es scheint mir also, als wuerde der Compiler die Uebergabe per Value aus g() raus einfach zu ner Uebergabe per Referenz machen, wenn es sich aussen um ne Deklaration handelt. Ziemlich abgefahren. Weiss einer, ob das immer so ist, oder ob das ne Optimierung vom Compiler ist?
 
Mitglied seit
01.01.1970
Beiträge
1.170
Reaktionen
0
3.
Operator= zu overloaden aendert nichts, der operator= wird gar nicht gecalled.

na kommt ja auch immer drauf an, was du in der methode dann machst.
und wenn dein überladener =operator gar nicht erst aufgerufen wird, dann hast was falsch gemacht und ihn nicht überladen.
 
Mitglied seit
15.09.2000
Beiträge
1.766
Reaktionen
418
Ne, ich bin mir ziemlich sicher nichts falsch gemacht zu haben. In dem Beispiel von Noxx wird der operator= nicht gecalled.

Die Zeile
XYZ result = g();
nimmt einfach nur die Referenz vom temporaeren Objekt und schreibt sie auf result. Insofern ist es auch egal, was man in den operator= reinschreibt.

Das passt auch dazu, dass es keinen zweiten Constructor/Destructor Call gibt.


Noch mein Code zu 3.: ich habe zu Noxx Code in der Class folgende Methode hinzugefuegt und der Output blieb unveraendert.

Code:
 XYZ& operator=(XYZ const &na)
  {
    cout << "operator=" << endl;
    n = na.n;
    return (*this);
  }
 
Mitglied seit
01.01.1970
Beiträge
1.170
Reaktionen
0
stimmt, hast recht, der operator= wird im ersten fall gar nicht verwendet.

der compiler macht aus:
XYZ result = g();
das hier:
XYZ result(g());

und wennde einen XYZ(const XYZ) constructor schreibst, wird dieser auch aufgerufen.

zb.
XYZ(const XYZ &na)
{
n = 5;
printf("anderer Constructor(): %d\n", n);
}
 
Mitglied seit
04.08.2002
Beiträge
1.869
Reaktionen
0
Thx, für die Antworten. Insbesondere der Wiki-Link ist hilfreich!
Habe das ganze gerade hier zu Hause mal mit dem Visual Studio 2010 Compiler getestet. Der optimiert das nicht, d.h. hier wird der Destruktor 2x aufgerufen.

Damit wäre die Frage aber geklärt ;)
 
Oben