Error: no matching function for call to....



  • Hallo Leute, wie der Titel schon sagt bräuchte ich Hilfe, ich habe heute zum ersten mal um es auszuprobieren kleine c++ Dateien geschrieben mit Vererbung und mehreren headern.
    Ich hab jetzt viele verschiedene Dinge ausprobiert und bekomme es nicht richtig kompiliert.

    Derzeit bekomme ich den Fehler: error: no matching function for call to 'CRaumschiff::CRaumschiff()'

    Und zwar einmal für den Abfangjaeger und einmal für den Minenleger.

    Hier mal die Codes:

    Die main:

    #include <iostream>
    #include "Abfangjaeger.hpp"
    #include "Minenleger.hpp"
    
    using namespace std;
    
    int main() {
        CMinenleger Miner;
        CAbfangjaeger Jaeger;
    
        Miner.Starten();
        Miner.Mine_Legen();
        Miner.Landen();
    
        Jaeger.Starten();
        Jaeger.Rakete_Feuern();
        Jaeger.Rakete_Feuern();
        Jaeger.Landen();
    
        return 0;
    }
    

    Raumschiff.cpp

    #include <iostream>
    #include "Raumschiff.hpp"
    
    using namespace std;
    
    CRaumschiff::CRaumschiff(int Farbe, int Energie) {
        m_Farbe = 0;
        m_Energie = 0;
        cout << "Neues Raumschiff erstellt" << endl;
    }
    
    void Starten() {
        cout << "Raumschiff startet!\n";
    }
    
    void Landen() {
        cout << "Raumschiff landet!\n";
    }
    

    Raumschiff.hpp

    #ifndef _Raumschiff_hpp
    #define _Raumschiff_hpp
    
    class CRaumschiff {
        protected:
    
            int m_Farbe;
            int m_Energie;
    
        public:
    
            CRaumschiff(int Farbe, int Energie);
            void Starten();
            void Landen();
    };
    
    #endif
    

    Abfangjaeger.cpp

    #include <iostream>
    #include "Abfangjaeger.hpp"
    
    using namespace std;
    
    CAbfangjaeger::CAbfangjaeger() {
        m_Raketen = 10;
        cout << "Neuer Abfangjaeger erstellt" << endl;
    }
    
    void CAbfangjaeger::Rakete_Feuern() {
        m_Raketen--;
    
        cout << "Rakete abgefeuert. Es sind noch " << m_Raketen;
        cout << " Raketen uebrig." << endl;
    }
    

    Abfangjaeger.hpp

    #ifndef _Abfangjaeger_hpp
    #define _Abfangjaeger_hpp
    #include "Raumschiff.hpp"
    
    class CAbfangjaeger : public CRaumschiff {
         private:
    
            int m_Raketen;
    
        public:
    
            CAbfangjaeger();
            void Rakete_Feuern();
    };
    
    #endif
    

    Minenleger.cpp

    #include <iostream>
    #include "Minenleger.hpp"
    
    using namespace std;
    
    CMinenleger::CMinenleger() {
        m_Minen = 10;
        cout << "Neuer Minenleger erstellt" << endl;
    }
    
    void CMinenleger::Mine_Legen() {
        m_Minen--;
    
        cout << "Mine gelegt. Es sind noch " << m_Minen;
        cout << " Minen uebrig." << endl;
    }
    

    Minenleger.hpp

    #ifndef _Minenleger_hpp
    #define _Minenleger_hpp
    #include "Raumschiff.hpp"
    
    class CMinenleger : public CRaumschiff {
        private:
    
            int m_Minen;
    
        public:
    
            CMinenleger();
            void Mine_Legen();
    };
    
    #endif
    


  • Der Konstruktor von CRaumschiff erwartet zwei Argumente, aber du gibst ihm keine. (Die erbenden Klassen müssen die geerbten Konstruktoren initialisieren.)
    Mal ein Beispiel:

    class A
    {
    public:
      A(int i)
      {}
    };
    
    class B : public A
    {
    public:
      B(int i)
        : A(i)
      {}
    };
    

    Und noch als Anmerkung: Klassennamen mit einem C am Anfang sind total out, nenn die Klassen einfach direkt Raumschiff etc.



  • Danke für die Schnelle Antwort 😉
    Ok, das ganze sind dann wohl so aus richtig?:

    Minenleger:

    #ifndef _Minenleger_hpp
    #define _Minenleger_hpp
    #include "Raumschiff.hpp"
    
    class CMinenleger : public CRaumschiff {
        private:
    
            int m_Minen;
    
        public:
    
            CMinenleger():CRaumschiff(10, 10){};
            void Mine_Legen();
    };
    
    #endif
    

    Abfangjaeger:

    #ifndef _Abfangjaeger_hpp
    #define _Abfangjaeger_hpp
    #include "Raumschiff.hpp"
    
    class CAbfangjaeger : public CRaumschiff {
         private:
    
            int m_Raketen;
    
        public:
    
            CAbfangjaeger():CRaumschiff(10, 10){};
            void Rakete_Feuern();
    };
    
    #endif
    

    Das bringt allerdings dann neue Fehler:
    Abfangjaeger.cpp:6:1 error: redefinition of 'CAbfangjaeger::CAbfangjaeger()'
    Abfangjaeger.hpp:12:9: error: 'CAbfangjaeger::CAbfangjaeger()' previously defined her

    Das gleiche für den Minenleger



  • Du darfst die Konstruktoren (wie auch jede andere Funktion) nur einmal definieren. Ich gehe mal davon aus, dass du die .cpp Dateien behalten hast. Jetzt hast du die Funktion aber ein mal in der Header und ein mal in der .cpp Datei definiert. Entscheide dich. 😉



  • cooky451 wollte dir damit aber nicht sagen, dass du es in der Header-Datei machen sollst. Du musst das ganze schon in der .cpp-Datei machen. 😉



  • Ja aber das habe ich getan, ich habe es in der cpp datei definiret:

    cpp datei:

    #include <iostream>
    #include "Minenleger.hpp"
    
    using namespace std;
    
    CMinenleger::CMinenleger() {
        m_Minen = 10;
        cout << "Neuer Minenleger erstellt" << endl;
    }
    
    void CMinenleger::Mine_Legen() {
        m_Minen--;
    
        cout << "Mine gelegt. Es sind noch " << m_Minen;
        cout << " Minen uebrig." << endl;
    }
    

    hpp datei:

    #ifndef _Minenleger_hpp
    #define _Minenleger_hpp
    #include "Raumschiff.hpp"
    
    class CMinenleger : public CRaumschiff {
        private:
    
            int m_Minen;
    
        public:
    
            CMinenleger():CRaumschiff(10, 10){};
            void Mine_Legen();
    };
    
    #endif
    

    wenn ich jetzt in der header datei die geschweiften klammer lösche, dann meckert der compiler das er sie da haben möchte



  • Vorschlag am Rande: Bastele mal alles insofern um, daß Du die Funktionen immer innerhalb der Klasse definierst und nur die main.cpp für die main() hast und viele Foo.hpp für die einzelnen Klassen.
    Das ist zwar nicht die heilige Lehre, aber ist praktisch, solange noch so arg an der Schnittstelle geändert wird.

    Später verschiebt man die Definitionen wieder in Foo.cpp, aber vorwiegend, um Compilezeit zu sparen. Ich denke mal, das ist hier noch kein Problem.



  • Das ist ja aber dann Fehler umgehen und nicht lösen 😉



  • void funktion(); // Deklaration --> ohne {} 
    void funktion() {} // Definition --> mit {}
    

    Und nun schau dir dein CMinenleger an. Du hast CMinenleger 2x definiert. In der Header und .cpp. Das gefällt dem Compiler gar nicht.

    CMinenleger::CMinenleger() : CRaumschiff(10, 10) {
        m_Minen = 10;
        cout << "Neuer Minenleger erstellt" << endl;
    }
    


  • Lybrial schrieb:

    Das ist ja aber dann Fehler umgehen und nicht lösen 😉

    Wenn das Umgehen den Fehler löst, ist es doch erstmal gut.
    Und dann kannst Du jederzeit so viel auslagern, wie Du willst, und es geht immernoch.

    Nein, ich wollte damit den Fehler gar nicht lösen, sondern es würde Dir beim Posten weniger Arbeit machen und uns beim Lesen. Aber hast recht, es löst vielleicht auch den Fehler.



  • Lybrial schrieb:

    Das ist ja aber dann Fehler umgehen und nicht lösen 😉

    Das was volkard beschreibt ist aber übliches Vorgehen bei dem Entwickeln einer neuen Klasse.
    Nun gut, dein Problem ist, dass die Initialisierungsliste zur Definition und nicht zur Deklaration gehört. Die muss also mit in die .cpp Datei.



  • Ist ja genau das was ich bei meinem letzten Post geschrieben hatte, sobald ich die {} also die definition aus der header datei rausnehme, da sie ja schon in der .cpp steht, bekomme ich folgende Fehlermeldung:

    Abfangjaeger.hpp: In constructor 'CAbfangjaeger::CAbfangjaeger{}':
    Abfangjaeger.hpp:12:43: error: expected '{' at end of input



  • Ich mag nochmal den Code sehen. 🙂



  • @Gugelmoser

    main.cpp:

    #include <iostream>
    #include "Abfangjaeger.hpp"
    #include "Minenleger.hpp"
    
    using namespace std;
    
    int main() {
        CMinenleger Miner;
        CAbfangjaeger Jaeger;
    
        Miner.Starten();
        Miner.Mine_Legen();
        Miner.Landen();
    
        Jaeger.Starten();
        Jaeger.Rakete_Feuern();
        Jaeger.Rakete_Feuern();
        Jaeger.Landen();
    
        return 0;
    }
    

    Raumschiff.cpp

    #include <iostream>
    #include "Raumschiff.hpp"
    
    using namespace std;
    
    CRaumschiff::CRaumschiff(int Farbe, int Energie) {
        m_Farbe = 0;
        m_Energie = 0;
        cout << "Neues Raumschiff erstellt" << endl;
    }
    
    void Starten() {
        cout << "Raumschiff startet!\n";
    }
    
    void Landen() {
        cout << "Raumschiff landet!\n";
    }
    

    Raumschiff.hpp

    #ifndef _Raumschiff_hpp
    #define _Raumschiff_hpp
    
    class CRaumschiff {
        protected:
    
            int m_Farbe;
            int m_Energie;
    
        public:
    
            CRaumschiff(int Farbe, int Energie);
            void Starten();
            void Landen();
    };
    
    #endif
    

    Minenleger.cpp

    #include <iostream>
    #include "Minenleger.hpp"
    
    using namespace std;
    
    CMinenleger::CMinenleger() {
        m_Minen = 10;
        cout << "Neuer Minenleger erstellt" << endl;
    }
    
    void CMinenleger::Mine_Legen() {
        m_Minen--;
    
        cout << "Mine gelegt. Es sind noch " << m_Minen;
        cout << " Minen uebrig." << endl;
    }
    

    Minenleger.hpp

    #ifndef _Minenleger_hpp
    #define _Minenleger_hpp
    #include "Raumschiff.hpp"
    
    class CMinenleger : public CRaumschiff {
        private:
    
            int m_Minen;
    
        public:
    
            CMinenleger():CRaumschiff(10, 10);
            void Mine_Legen();
    };
    
    #endif
    

    Abfangjaeger.cpp

    #include <iostream>
    #include "Abfangjaeger.hpp"
    
    using namespace std;
    
    CAbfangjaeger::CAbfangjaeger() {
        m_Raketen = 10;
        cout << "Neuer Abfangjaeger erstellt" << endl;
    }
    
    void CAbfangjaeger::Rakete_Feuern() {
        m_Raketen--;
    
        cout << "Rakete abgefeuert. Es sind noch " << m_Raketen;
        cout << " Raketen uebrig." << endl;
    }
    

    Abfangjaeger.hpp

    #ifndef _Abfangjaeger_hpp
    #define _Abfangjaeger_hpp
    #include "Raumschiff.hpp"
    
    class CAbfangjaeger : public CRaumschiff {
         private:
    
            int m_Raketen;
    
        public:
    
            CAbfangjaeger():CRaumschiff(10, 10);
            void Rakete_Feuern();
    };
    
    #endif
    


  • Lies doch bitte meine Posts:

    cooky451 schrieb:

    Lybrial schrieb:

    Das ist ja aber dann Fehler umgehen und nicht lösen 😉

    Das was volkard beschreibt ist aber übliches Vorgehen bei dem Entwickeln einer neuen Klasse.
    Nun gut, dein Problem ist, dass die Initialisierungsliste zur Definition und nicht zur Deklaration gehört. Die muss also mit in die .cpp Datei.



  • Initalisierungsliste?



  • class CMinenleger : public CRaumschiff {
        private:
    
            int m_Minen;
    
        public:
    
            CMinenleger(); // so <-- das hier ist eine Deklaration.
            void Mine_Legen();
    };
    
    CMinenleger::CMinenleger() : CRaumschiff(10,10)  { // <-- das hier ist eine Definition.
        m_Minen = 10;
        cout << "Neuer Minenleger erstellt" << endl;
    }
    

    Das Anderen schaffst du das bestimmt alleine. 😉



  • Darf man Fragen womit du C++ lernst. Immerhin kennst du schon Vererbung, aber keine Initialisierungsliste?



  • Na Grundsätzlich weiß ich schon was eine Initialisierungsliste ist...
    Nur in dem Post auf Post und Antwort auf Antwort kuddel-muddel, wusste
    ich einfach nicht mehr was genau gemeint war, schließlich habe ich ja
    mehrere Initialisierungen 😉

    Eine undefined reference habe ich aber nach wie vor:

    C:\User\"Username"\AppData\Local\Temp\cczGoxZa.o:main.cpp:(.text+0x2e): undefined reference to 'CRaumschiff::Starten()'

    das gleiche für Landen()
    und noch mal Starten() und Landen()



  • Du musst dem Compiler schon sagen, dass deine starten-Funktion eine Zugehörigkeit hat, etc.

    void CRaumschiff::Starten() {
        cout << "Raumschiff startet!\n";
    }
    


  • In Raumschiff.cpp fehlt für die entsprechenden Funktionen das Klassenprefix. (Oder wie auch immer das Ding heißt.)
    Aber wie wäre es, wenn du einfach mal die Fehlermeldungen liest?


Anmelden zum Antworten