Übung zur Polymorphismus -> Fehler: "Nicht aufgelöstes externes Symbol"



  • Aufgabenstellung:

    (a) Erstellen Sie eine Klasse Fahrzeug und deklarieren Sie die privaten Variablen
    ps und year als Integer. Programmieren Sie den Konstruktor zur Initialisie-
    rung der beiden Variablen. Weitergehend soll eine Methode print() erstellt
    werden, die die Variablen mit cout ausgibt.
    (b) Erstellen Sie nun eine Klasse Auto und Boot, die die Klasse Fahrzeug als
    Oberklasse haben. Die Klasse Auto soll eine Variable counterDoors und die
    Klasse Boot eine Variable length enthalten. Programmieren Sie wieder einen
    Konstruktor zur Initialisierung der zusätzlichen Variablen. Beide Klassen sol-
    len jeweils eine Methode print() zum Ausgeben aller Variablen enthalten.
    (c) Mit Hilfe von Polymorphismus unter der Benutzung der print-Methode soll
    die Ausgabe aller Variablenwerten ausgegeben werden

    soweit so gut, habe ich bis dahin auch glaube ich alles gemacht:

    Fahrzeug.h

    class Fahrzeug
    {
    
    private:	int ps,year;
    
    public:		Fahrzeug();
    			Fahrzeug(int ps, int year);
    
    			void print();
    
    			~Fahrzeug(void);
    };
    

    Fahrzeug.cpp

    #include "stdafx.h"
    #include "Fahrzeug.h"
    
    Fahrzeug::Fahrzeug(int PS, int YEAR) : ps(PS), year(YEAR)
    {
    }
    
    void Fahrzeug::print()
    {
    	cout << ps << ", " << year  << endl;
    }
    
    Fahrzeug::~Fahrzeug(void)
    {
    }
    

    Auto.h

    #include "fahrzeug.h"
    
    class Auto :	public Fahrzeug
    {
    
    private:	int counterDoors;
    
    public:		Auto();
    			Auto(int counterDoors);
    
    			void print();
    
    			~Auto(void);
    };
    

    Auto.cpp

    #include "stdafx.h"
    #include "Auto.h"
    
    Auto::Auto(int cD) : counterDoors(cD)
    {
    }
    
    void Auto::print()
    {
    	cout << counterDoors << endl;
    }
    
    Auto::~Auto(void)
    {
    }
    

    mit Boot genauso ...

    in der stdafx.h stehen:

    #include "targetver.h"
    
    #include <stdio.h>
    #include <tchar.h>
    #include <iostream>
    
    using namespace std;
    

    ich habe noch nichts in der main stehen und wollte erstmal kompilieren, jedoch kommen 3 Fehler:

    Fehler 1: error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Fahrzeug::Fahrzeug(void)" (??0Fahrzeug@@QAE@XZ)" in Funktion ""public: __thiscall Auto::Auto(int)" (??0Auto@@QAE@H@Z)".

    Fehler 2: error LNK2001: Nicht aufgelöstes externes Symbol ""public: __thiscall Fahrzeug::Fahrzeug(void)" (??0Fahrzeug@@QAE@XZ)".

    Fehler 3: error LNK1120: 1 nicht aufgelöste Externe

    Ich habe natürlich schon gesucht, aber es gibt sooo viel zu diesem Fehler, dass ich nicht mehr klar komme 😕

    Es wird halt auch nichts rot unterstrichen oder so, dass man wenigstens weiß wo man schauen muss und das ist für mich als Anfänger nicht ganz einfach 😞

    aber die profis hier kennen den Fehler wahrscheinlich schon, bevor sie anfangen zu lesen 👍 🙂



  • Das Frage Antwort Spiel:

    Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Fahrzeug::Fahrzeug(void)"
    

    Wenn Du ganz genau liest: Welcher Teil Deines Source wird vom Linker angemäkelt?



  • Der Konstruktor der Klasse Fahrzeug!? Aber die frage ist ja eher das WIESO 😕

    also wenn ich

    Fahrzeug::Fahrzeug(int PS, int YEAR) : ps(PS), year(YEAR)
    {
    }
    

    durch

    Fahrzeug::Fahrzeug()
    {
    }
    

    ersetze, geht es :- /

    aber ich brauche doch diese Initialisierungsliste um die Variablen zu initialisieren!? Wieso muss ich da jetzt einfach den Standardkonstruktor hinschreiben?



  • spell schrieb:

    Der Konstruktor der Klasse Fahrzeug!? Aber die frage ist ja eher das WIESO 😕

    Okay.
    Es geht um den Konstruktor Fahrzeug::Fahrzeug(); aka. Standardkonstruktor.

    Hier ist die Deklaration:

    class Fahrzeug
    {
    
    private:    int ps,year;
    
    public:     Fahrzeug();
                Fahrzeug(int ps, int year);
    
                void print();
    
                ~Fahrzeug(void);
    };
    

    Nächste Frage:
    Wo ist die Definition? D.h. wo hast Du den Konstruktor implementiert?



  • Furble Wurble schrieb:

    Nächste Frage:
    Wo ist die Definition? D.h. wo hast Du den Konstruktor implementiert?

    Den Standardkonstruktor habe ich nirgens implementiert. Muss man das? Ich stehe mit dem Konstruktor noch auf Kriegsfuß 😡
    Habe mir einfach gemerkt das der immer in die .h weil der compiler sonst meckert dass keiner da ist



  • spell schrieb:

    aber ich brauche doch diese Initialisierungsliste um die Variablen zu initialisieren!? Wieso muss ich da jetzt einfach den Standardkonstruktor hinschreiben?

    Editieren ist unfair! 🙂

    Zwei Gründe: erstmal hast Du in der Klassendefinition einen Standardc'tor deklariert, also musst Du auch liefern.

    zweitens, schau hier:

    class Auto : public Fahrzeug{ /* ... */ };
    
    Auto::Auto(int cD) : counterDoors(cD)
    {
    }
    

    Hier wird der Standardc'tor von Fahrzeug auch aufgerufen.
    Richtig?



  • Furble Wurble schrieb:

    Hier wird der Standardc'tor von Fahrzeug auch aufgerufen.
    Richtig?

    ja, weil in diesen geschwungenen Klammern nichts steht oder !?

    Uns wurde das so beigebracht, dass es 2 Typen gibt

    1x die mit Parameterübergabe

    also Klasse (int foo){Variable=foo}

    und 1x mit Initialisierungsliste (was wir eher verwenden sollten weil es irgendwie "richtiger" ist und das andere bei vererbung nicht funktionieren würde.

    Klasse (int foo) : Variable(foo) {}

    jetzt habe ich in der .h zB public: Boot(int length);

    und in der cpp dann Boot::Boot(int l) : length(l)
    {

    }

    und er meckert, dass kein Standardkonstruktor vorhanden sei 😡

    also hab ich einfach ienen in die .h geschrieben. Nur bei der Klasse Fahrzeug kommt er dann eben mit diesen Fehlern.

    edit: muss mal 10min weg ^^



  • spell schrieb:

    Furble Wurble schrieb:

    Hier wird der Standardc'tor von Fahrzeug auch aufgerufen.
    Richtig?

    ja, weil in diesen geschwungenen Klammern nichts steht oder !?

    Richtig, aber die Begründung ist falsch. Der leere Rumpf hat damit erstmal nichts zu tun.

    Der Grund ist vielmehr, dass Du keinen C'tor explizit aufrufst. Und damit wird der Standardc'tor bemüht.

    Da Auto von Fahrzeug erbt, hat jedes Auto ein Base-class Subobjekt vom Typ Fahrzeug.
    Dieses wird auch als erstes initialisiert, wenn Du ein Auto erstellst.

    Ein richtiger C'tor für Auto könnte also so aussehen:

    Auto::Auto(int ps, int year, int cD) : Fahrzeug(ps, year), counterDoors(cD)
    {
    }
    

    Du siehst ich benutze explizit einen bestimmten C'tor von Fahrzeug.
    Soweit so klar?



  • Parallel zu deiner Antwort ist mir das auch eingefallen und ich wollte es mit

    Auto::Auto(int Leistung, int Jahr, int Tueren ) : ps(Leistung), year(Jahr), counterDoors(Tueren)
    {
    }
    

    lösen, was auch nicht ging. Aber jetzt hast du mir die richtige Syntax gezeigt und siehe da, mit

    Auto::Auto(int Leistung, int Jahr, int Tueren ) : Fahrzeug(Leistung,Jahr), counterDoors(Tueren)
    {
    }
    

    geht es auch endlich 👍

    vielen DANK! ❤



  • spell schrieb:

    vielen DANK! ❤

    Gern geschehen!

    Dann noch viel Erfolg! 🙂


Anmelden zum Antworten