C++: Destruktor an falscher Stelle

OP Persönliche Seite #3072566
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.
Gast #3072593
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
#3072638
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.
#3073371
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren