Forum: PC-Programmierung C++: Destruktor an falscher Stelle


von Maxim (maxim) Benutzerseite


Lesenswert?

Ein Objekt a der Klasse A soll ein Objekt b der Klasse B besitzen.
1
class A
2
{
3
public:
4
  A();
5
  ~A();
6
7
  B b;
8
};

Im Konstruktor von A steht:
1
b = B(7);

Erzeuge ich hierbei zweimal ein Objekt der Klasse B? Ich hatte naemlich 
Probleme mit dem Destruktor, der offensichtlich etwas zerstoeren wollte, 
was nicht da war. B legt intern einige Objekte nur an, wenn ein 
Konstruktor mit Parametern aufgerufen wird. Geloest habe ich es dadurch, 
dass ich in A nur einen Zeiger auf ein Objekt der Klasse B definiert und 
im Konstruktor von A dann
1
b = new B(7);

verwendet habe.

von Steffen (Gast)


Lesenswert?

Hallo Maxim,
1
b = B(7);
erzeugt B(7), kopiert das Object nach b, und zerstört das Originalobjekt 
danach. Manche Compiler könnten den copy c'tor aber auch wegoptimieren.

wie sieht es denn aus mit:
1
A::A() : b(7) 
2
{
3
} ;

Grüße Steffen

von Karl H. (kbuchegg)


Lesenswert?

Maxim S. schrieb:

> Erzeuge ich hierbei zweimal ein Objekt der Klasse B?

Ja, natürlich.

Das erste B-Objekt wird erzeugt, wenn das A-Objekt erzeugt wird, weil ja 
jedes A Objekt einen B-Member hat. Und diesen B-Member muss es bereits 
haben, wenn der Funktionskörper des Konstruktors beginnt loszulaufen.
Im Konstruktor tauscht du dann diese Default-erzeugte Objekt gegen ein 
neues aus. Und dabei wird natürlich das zuerst erzeugte Objekt zerstört.


> Ich hatte naemlich
> Probleme mit dem Destruktor, der offensichtlich etwas zerstoeren wollte,
> was nicht da war. B legt intern einige Objekte nur an, wenn ein
> Konstruktor mit Parametern aufgerufen wird. Geloest habe ich es dadurch,
> dass ich in A nur einen Zeiger auf ein Objekt der Klasse B definiert und
> im Konstruktor von A dann
>
>
1
> b = new B(7);
2
>
>
> verwendet habe.

Keine gute Idee.
Du solltest ernsthaft den Ankauf und das Durcharbeiten eines C++ Buchs 
in Erwägung ziehen! Und das meine ich nicht als Scherz oder weil ich 
dich ärgern will.

Sowas macht man mit einer Initializer List im Konstruktor ...
1
class A
2
{
3
public:
4
  A();
5
  ~A();
6
7
  B b;
8
};
9
10
A::A() : b( 7 )
11
{
12
}

... in der festgelegt wird, auf welche Art und Weise der B-Member des 
A-Objektes zu erzeugen ist.

Wie willst du denn C++ programmieren, wenn du die Hälfte deines 
Werkzeugkastens gar nicht kennst?


> Geloest habe ich es dadurch,
> dass ich in A nur einen Zeiger auf ein Objekt der Klasse B definiert
> und im Konstruktor von A dann
> b = new B(7);
>
> verwendet habe.

Das kann man so machen, manchmal muss man es so machen, aber wenn irgend 
möglich, willst du es ohne erzwungenen Grund nicht so machen. Bis jetzt 
seh ich noch nichts, was diesen Weg erzwingen würde.

Grund: dynamische Allokierung erfordert bei einer sauber allokierten 
Klasse einen Destruktor, einen Copy Contruktor und einen 
Zuweisungsoperator. Auch bekannt als die 'Rule of three': Musst du eine 
der 3 selbst implementieren - Destruktor, Copy Constructor, Assigment 
operator - ist es sehr wahrscheinlich, dass du alle 3 implementieren 
musst.

von Mark B. (markbrandis)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Keine gute Idee.
> Du solltest ernsthaft den Ankauf und das Durcharbeiten eines C++ Buchs
> in Erwägung ziehen! Und das meine ich nicht als Scherz oder weil ich
> dich ärgern will.

Absolute Zustimmung. Und wenn hier einer andere ärgert, dann doch wohl 
eher derjenige der sich weigert ein Buch zu kaufen und erstmal die 
Grundlagen einer Sprache zu erlernen.

von Steffen (Gast)


Lesenswert?

Hallo Maxim S.,

nicht entmutigen lassen. Anfangs kann man schon Mal den Überblick 
verlieren.

Grüße, Steffen

von Maxim (maxim) Benutzerseite


Lesenswert?

Danke euch fuer die Antworten und fuer die Ermutigung. ;) Das aktuelle 
Projekt laeuft gerade zu Ende und bisher war objektorientierstes 
Programmieren nicht noetig. Fuer's naechste Projekt werde ich mir sicher 
ein C++-Buch anschaffen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.