Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » C++ Constructor - Destructor Problem

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
27.01.2006, 11:36 Uhr
~UlfB
Gast


Hallo allerseits,

mir ist da ein Unterschied zwischen GCC und MSVC6 aufgefallen. Wenn eine Methode ein Objekt zurückgibt, dann läuft bei MSVC vor der Rückgabe aus der Methode der Destruktor des zurückzugebenden Objekts ab. Das ist ziemlich ärgerlich, was soll ich mit einem Objekt, dessen Destruktor schon gelaufen ist? Unter GCC läuft alles wie erwartet, der Destruktor wird am Ende des Scopes der "main" Klammerung ausgeführt.

Hat dafür jemand eine Erklärung?

Hier der Beispiel-Code:


C++:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

class Data
{
public:
  Data(const char *str)
  {
    m_str = new char[256];
    strcpy(m_str, str);
    printf("Constructor (%s)\n", str);
  }

  ~Data()
  {
    printf("Destructor  (%s)\n", m_str);
    delete m_str;
  }

  inline const char *getStr()
  {
    return m_str;
  }
protected:
  char *m_str;
};

Data createData()
{
  Data d("Created inside method");

  return d;

  // hier ist der Destruktor von d bereits gelaufen (nur bei MSVC)
}

/****************************************************************************/

int main(int argc, char *argv[])
{
  {
    Data d = createData();

    printf("Data d = [%s]\n", d.getStr());

    // hier kommt der Destruktor von d (aber nur bei GCC!)
  }
  fgetc(stdin);
  return 0;
}



mod edit: benutze die CPP TAG SELBER!

Dieser Post wurde am 27.01.2006 um 11:43 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
27.01.2006, 11:51 Uhr
~UlfB
Gast


An Mod:

Sorry, ich wußte nicht, daß es sowas wie CPP Tags gibt :-)

Aber sieht cool aus!

Ulf
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.01.2006, 12:19 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Spontan würde ich sagen implementiere einen copy-construktor und übelade den zuweisungsoperator....
--
...fleißig wie zwei Weißbrote

Dieser Post wurde am 27.01.2006 um 12:25 Uhr von Windalf editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.01.2006, 12:28 Uhr
~UlfB
Gast


Das wäre dann "ein Pflaster auf dieWunde kleben" :-). Klar kann ich das Problem umgehen, die Frage wäre hier, welcher Kompiler baut den "richtigen" Code?

Das Problem scheint vor allem so trivial zu sein, das ich mit denke: "Das müßte doch schon jemandem aufgefallen sein!"

Oder mache ich da einen Denkfehler?

Ulf
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
27.01.2006, 12:38 Uhr
~UlfB
Gast


Ich haber gerade folgendes herausgefunden:

Wenn ich die Methode "createData" wie folgt ändere, dann läuft es so, wie erwartet.

(Hoffentlich ist das so richtig mit dem CPP-Tag)

C++:
Data createData()
{
return Data("Created inside method");
}
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
27.01.2006, 12:40 Uhr
~UlfB
Gast


Jetzt habe ich's mit dem Tag kapiert, sorry, bin etwas langsam heute. Also nochmal:

[CPP]
Data createData()
{
return Data("Created inside method");
}
[/CPP]
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
27.01.2006, 12:41 Uhr
~UlfB
Gast


An den Mod: Nicht schimpfen...


C++:
Data createData()
{
return Data("Created inside method");
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
27.01.2006, 13:06 Uhr
virtual
Sexiest Bit alive
(Operator)


Schaun wir uns doch mal folgende Routine an:

C++:
Data createData()
{
  Data d("Created inside method");
  return d;
}


Die ist identisch mit der in Post 006 geschrieben methode, dh es werden exakt die gleiche ctor/dtor aufrufe gemacht. Und dann noch einen Aufruf:

C++:
Data r = createData();


Es passiert folgendes:

Code:
In createData:
1. Aufruf ctor für d
2. Aufruf des Copy-ctors für r, um eine Kopie zu von d zu erzeugen
3. Aufruf des dtors für d.
Nun sind wir wieder ausserhalb von createData, dann irgendwann:
4. Aufruf des dtors für r.


Da du den copy-ctor nicht überschrieben hast, siehst Du (2) auch niemals.

So wie es da oben steht, ist es die reine Lehre, aber es ist ziemlich klar, daß Du eigentlich nur das Objekt r brauchst, das d object eigentlich garnicht. Manche Compiler können das erkennen und sparen sich daher die initialisierung von d. Siehe auch: http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Optimize#Answ
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 27.01.2006 um 13:07 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
27.01.2006, 13:09 Uhr
virtual
Sexiest Bit alive
(Operator)


Ach übrigens: Du musst - wie der Troll. vom Dienst (Windalf) bereits geschrieben hat - den Zuweisungsoperator und den Copyctor überschrieben, sonst bekommst Du Probleme.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
27.01.2006, 13:13 Uhr
(un)wissender
Niveauwart


Wie schon gesagt: nicht der Compiler macht hier Fehler, sondern du.
Ohne den Kopierkonstruktor kann die Klasse nicht funktionieren: Du erschafft ein temp. Objekt, das wird bitweise kopiert (Default copy constr.), das temp. Objekt löscht m_str und dein kopiertes Objekt hat einen ungültigen Zeiger.


Bearbeitung:

Zu langsam;).
Und klar, wenn copy constuktor überschreiben, dann auch immer zuweisung (operator=).


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 27.01.2006 um 13:15 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: