Constructor Problem

Gast #181340
Lesenswert?

Hallo ...

Angenommen ich hab eine Klasse wie
class bla1 {
public:
    bla1();
    ~bla1();
};

und

class bla2 {
public:
    bla2();
    ~bla2();

private
    bla1     m_meinbla1;
};

bla2::bla2() {
    PortsInitialisieren();
}

und ich erzeuge ein Objekt meiner Klasse bla2 mittels:
int main() {
  bla2 meinbla2 = bla2();
  for(;;) {}
}

Jetzt die große Frage - wird der Constructor von bla1 beim Erzeugen des
Objektes bla2 auch noch gleich aufgerufen, weil ja bla1 auch erzeugt
wird?

Und ich nehme an, dass das bereits noch vor PortsInitialisieren()
(siehe constructor bla2) passiert?

Falls das so ist, wäre das nicht so besonders toll ...
Mein Problem ist, dass ich eine LCD-Klasse habe und laut dem
AVR-Simulator wird gleich der Konstructor der LCD-Klasse aufgerufen
bevor die Ports im Constructor der Hauptklasse (hier bla2)
initialisiert werden ... Eine Lösung wäre eine zweistufige
Initialisierung (Constructor + Init()-Methode) ...

Weiß da jemand was genaues?

Mfg
Thomas
Gast #181342
Lesenswert?

Ja - wieso sollten die Vorteile von C++ auf dem AVR nicht mehr existent
sein?

Ich rechnete eigentlich erst mit einem erheblichen Overhead für die
Objekte - aber das ist überhaupt nicht so!

Einen Geschwindigkeitsverlust hab ich auch nicht bemerkt ...
Gast #181343
Lesenswert?

> wird der Constructor von bla1 beim Erzeugen des
> Objektes bla2 auch noch gleich aufgerufen, weil ja bla1
> auch erzeugt wird?

Ja.

> Und ich nehme an, dass das bereits noch vor PortsInitialisieren()
> (siehe constructor bla2) passiert?

Ja.

> wird gleich der Konstructor der LCD-Klasse aufgerufen
> bevor die Ports im Constructor der Hauptklasse (hier bla2)
> initialisiert werden

Und genau da liegt dein Designfehler. Jedes Modul sollte die ihm
zugeornete Hardware selbst initialisieren. Das ist ja grad der Witz am
Modulen (egal ob C oder C++). Jedes erledigt seinen eigenen Kram.
Gast #181344
Lesenswert?

"Und genau da liegt dein Designfehler. Jedes Modul sollte die ihm
zugeornete Hardware selbst initialisieren. Das ist ja grad der Witz am
Modulen (egal ob C oder C++). Jedes erledigt seinen eigenen Kram."

Jo - da muss ich dir recht geben ... Da hab ich echt nicht aufgepasst
... Ich hatte das irgendwie so drin, am Anfang die ganzen
Portinitialisierungen zu machen.

Das war auch wirklich der Fehler ... mittlerweile gehts schon :)
Gast #181345
Lesenswert?

Nur für den Fall, dass du auf die Idee kommt, Ports und LCD mittels
globaler Objekte zu initialisieren:
Wenn du eine globale Instanz einer Klasse erstellst, wird der
Konstruktor ja vor main() aufgerufen. Das Entscheidende ist aber, dass
die Reihenfolge der Konstruktoraufrufe weder festgelegt noch
feststellbar ist.
Aus genau diesem Grund sollte man z.B. std::cout nicht in einem
Konstruktor benutzen, der möglicherweise von einem globalen Objekt
aufgerufen wird.

Aber globale Objekte benötigt man in C++ sowieso nur selten, am
häufigsten noch für ein bestimmtes Pattern, wenn es ums automatische
Initialisieren geht (dann sind die Objekte eh in einem namespace).
Gast #181346
Lesenswert?

Danke für den Hinweis - aber ich hab nur ein einziges Globales Objekt -
das ist das Objekt, das mir alle meine anderen Objekte (Timer, LCD,
RS232, usw) verwaltet ... Ich denke mal, da ist es genauso, dass man
nicht sagen kann in welcher Reihenfolge die Konstruktoren aufgerufen
werden. Davon bin ich aber gottseidank auch nicht abhängig :-)
Gast #181347
Lesenswert?

> Ich denke mal, da ist es genauso, dass man
> nicht sagen kann in welcher Reihenfolge die Konstruktoren
> aufgerufen werden.

Objekte innerhalb von Klassen werden grundsätzlich in der Reihenfolge
konstruiert, in der sie deklariert wurden (bin mir da ziemlich sicher).
Nicht davon abhängig sein, ist natürlich die bessere Variante. :)

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