Compiler fordert Standardkonstruktor



  • Servus,

    ich habe eine Klasse Xy, die als Attribut der Klasse Z hat. Jetzt wollte ich gerne die Standardkonstruktoren ausschalten, habe also nur noch die Konstruktoren genommen die ich brauche.

    Jetzt nörgelt der Compiler, dass es keinen Standardkonstruktor gibt. Aber ich frage mich gerade, warum der Standardkonstruktor von der Klasse Msa überhaupt gerufen wird ?!

    Danke vorab.

    class H2r {
    
    private:
        Msa msa;
    
    public:
        //H2r() {
            //cout << "H2r-construct( default )\n";
            //cout << "... // H2r-construct()\n";
        //}
    
        H2r( Msa& m ) {
            //cout << "H2r-construct( Msa m )\n";
            this->msa = m;
            //cout << "... // H2r-construct()\n";
        }
    

    ... error: no matching function for call to ‘Msa::Msa()’



  • Weil msa bei diesem Aufruf

    this->msa = m;
    

    schon konstruiert ist. Besser wäre

    class H2r {
    
    private:
        Msa msa;
    
    public:
        H2r( Msa& m ) : msa( m ) {
        }
    


  • Ausserdem würde ich die Referenz auf ein konstantes Objekt zeigen lassen:

    H2r(const Msa& m);
    


  • Initialisierung von membern findet VOR der ausführung des Konstruktors statt. (in deinem Fall wird Msa initialisiert, bzw konstruiert bevor H2R(Msa& m) aufgerufen wird) Gibt es keinen Standardkonstruktor für die Initialisierung muss man die nötigen variablen, wie Manni66 geschrieben hat, in einer Initilisierungsliste angeben.



  • kleiner Troll schrieb:

    ...

    Ich schreibe das ganze mal etwas verständlicher um:

    Innerhalb des Konstruktorrumpfes existiert das Objekt bereits, und somit sind die Initialisierungen bereits abgeschlossen, es finden hier nur noch Zuweisungen statt.

    Der Konstruktor verfügt aber neben den Rumpf noch über eine Initialisierungsliste, in der die Initialisierung beeinflusst werden kann (u.a. wichtig bei Vererbung, wenn die Basisklasse keinen Standardkonstruktor anbietet, bei Konstanten, Referenzen...).

    class A
    {
      private:
        int a;
        int b;
    
      public:
        A()
        : a(0), b(1) // <-- Initialisierungsliste
        {
           // <-- Konstruktorrumpf
        }
    };
    

    Eins muss man bei der Initialisierungsliste beachten: Die Initialisierung findet in Reihenfolge der Memberdeklaration statt (sprich, wenn ich oben a und b in der Initialisierungsliste vertausche wird dennoch a zuerst initialisiert, da weiter oben deklariert). Dies ist wichtig wenn man Initialisierungen voneinander abhängig macht.



  • kleiner Troll schrieb:

    Initialisierung von membern findet VOR der ausführung des Konstruktors statt.

    Nein. Strenggenommen gehört die Initialisierung von Basisklassen und Membern zur Ausführung des Ctor mit dazu - es wird aber vor Betreten des Konstruktorrumpfes (Funktionsrumpfes des Ctors) initialisiert.

    (in deinem Fall wird Msa initialisiert, bzw konstruiert bevor H2R(Msa& m) aufgerufen wird)

    Nein. Der Konstruktor wird aufgerufen, erst nach dem Aufruf wird initialisiert, aber eben vor dem Rumpf. Erkennt man auch daran, dass die Argumente des Aufrufs in der Initialisierungsliste verwendet werden können.



  • Gut, hast natürlich recht, hab ich so nicht bedacht.


Anmelden zum Antworten