Constructor Problem

Gast #181340
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
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
> 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
"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
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
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
> 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

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.