Vererbung und Überschreiben von STDOUT



  • da haben wir uns jetzt überkreuzt 🙂

    deine letzte Antwort hat mir mein Problem gelöst !

    Danke 😃 👍



  • Es ist leider noch immer so, dass die WRITE-Methode der Superklasse aufgerufen wird - ganz egal welches Objekt ich in den Vector stecke :(:(

    woran kanns da noch liegen ?

    vielleicht erbarmt sich noch jemand meiner... 🙂



  • TanjaAnke schrieb:

    Es ist leider noch immer so, dass die WRITE-Methode der Superklasse aufgerufen wird - ganz egal welches Objekt ich in den Vector stecke :(:(

    woran kanns da noch liegen ?

    vielleicht erbarmt sich noch jemand meiner... 🙂

    Zeig mal den Code, der die Instanzen in den vector packt.

    mfg
    v R



  • wie "niemand" vorgeschlagen hat, hab ich jetzt den Vektor in

    std::vector<TestClassA*> Testi;
    

    geändert

    Beim Aufruf von

    Testi.push_back(TestClassB(alter,gewicht,groesse));
    

    kommt dann plötzlich

    :\test\test.cpp(97) : error C2664: 'push_back' : Konvertierung des Parameters 1 von 'class TestClassB' in 'class TestClassA *const & ' nicht moeglich
    Ursache: Konvertierung von 'class TestClassB' in 'class TestClassA *const ' nicht moeglich



  • Testi.push_back(new TestClassB(alter,gewicht,groesse));
    

    delete nicht vergessen
    Kurt



  • Es muss

    Testi.push_back( new TestClassB( alter,gewicht,groesse));
    

    heissen.



  • Das ist auch richtig. Du speicherst jetzt einen Zeiger auf TestClassA-Instanzen
    ab und musst natuerlich auch entsprechende liefern:

    Testi.push_back(new TestClassB(alter,gewicht,groesse));
    

    Du erstellst jetzt dynamisch eine Instanz der Klasse TestClassB, welche an
    'TestClassA*' zugewiesen werden kann.

    Was du auf jeden Fall jetzt beachten musst: Du reservierst Speicher dynamisch und
    musst diesen folglich auch wieder freigeben:

    //irgendwo bei programm ende
    for(size_t i = 0; i < Testi.size(); ++i)
        delete Testi[i];
    

    mfg
    v R



  • Es ist zwar jetzt so dass die Fehlermeldung weg ist - der Aufruf der write-Methode erreicht aber jetzt weder die der SuperKlasse noch die der erbenden Klasse.

    Und laut Debugger ist da wieder nur ein TestClassA-Objekt drinnen - d.h. nur die Basis-Variablen sind vorhanden

    PS: ich habe jetzt auch mit dem Debugger festgestellt dass beim Aufruf, also bei

    Testi.push_back(new TestClassB(alter,gewicht,groesse));
    

    alle Werte richtig befüllt wurden...

    Das Ganze wird dann an den Konstruktor

    TestClassB::TestClassB(int alter, int gewicht, int groesse_in) 
    	: TestClassA(alter, gewicht)
    {
    	groesse = groesse_in;
    }
    

    und trotzdem kommt am schluss immer ein TestClassA-Objekt in den Vector....



  • TanjaAnke schrieb:

    Es ist zwar jetzt so dass die Fehlermeldung weg ist - der Aufruf der write-Methode erreicht aber jetzt weder die der SuperKlasse noch die der erbenden Klasse.

    Und laut Debugger ist da wieder nur ein TestClassA-Objekt drinnen - d.h. nur die Basis-Variablen sind vorhanden

    Selbstverstaendlich ist nur ein TestClassA-Objekt im vector enthalten. Aber da
    TestClassB und TestClassC von TestClassA erben, ist diese Zuweisung legitim.

    Zu deinem Problem:
    Kannst du den Code mal hier: http://rafb.net/paste/ posten und den Link hier
    reinstellen?

    mfg
    v R



  • Ich habe jetzt gleichmal das Original gepostet und nicht mehr meine Fantasie-Klassen 🙂

    Es gibt die Klasse Fahrzeug = Oberklasse = entspricht TestClassA
    und Klasse PKW = erbende Klasse = entspricht TestClassB

    Die Main ist in einem weiteren externen File und arbeitet mit dem Vector

    http://rafb.net/paste/results/iLaPZm53.html



  • Hallo,

    die 'friend'-Deklarationen benoetigst du nicht. Das Problem das du hast:
    Du hast lediglich eine Definition von
    'std::ostream& operator<<(std::ostream& out, const Fahrzeug& val)' in der
    .cpp-Datei. Du musst diese aber auch in der Header haben, sonst ist der op<<
    ja gar nicht bekannt.

    Mir ist noch aufgefallen, dass es hier Fahrzeug* sein muss. Dein Programm sieht
    also so aus:

    fahrzeug.h

    #ifndef FUHRPARK_FAHRZEUG_H_INCLUDED
    #define FUHRPARK_FAHRZEUG_H_INCLUDED
    
    #include <string>
    
    class Fahrzeug
    {
    	public:
    		Fahrzeug(char car_type[20],char plate[8],int age, int performance);
    		~Fahrzeug();
    
    		void change_plate(char plate[8]);
    		void show_car();
    		virtual void write (std::ostream& out)const;
    
    		char car_type[20];
    		char plate[8];
    		int age;
    		int performance;
    };
    
    std::ostream& operator<<(std::ostream& out, const Fahrzeug* val);
    
    #endif
    

    fahrzeug.cpp

    #include <iostream>
    #include <string>
    #include "Fahrzeug.hpp"
    
    using namespace std;
    
    Fahrzeug::Fahrzeug(char car_type_in[20], char plate_in[8],int age_in, int performance_in)
    {
    	cout << "Neues Fahrzeug eingestellt " << endl;
    	strcpy(car_type,car_type_in);
    	strcpy(plate,plate_in);
    	age = age_in;
    	performance = performance_in;
    }
    
    Fahrzeug::~Fahrzeug()
    {
    }
    
    void Fahrzeug::change_plate(char input[])
    {
    	strcpy(plate,input);
    }
    
    void Fahrzeug::show_car()
    {
    	cout << "Kennzeichen: ";
    	for (int i=0;i<8;i++) {
    		cout << plate[i];
    	}
    	cout << "      Baujahr: "<< age <<"      Leistung: "<< performance << endl;
    }
    
    void Fahrzeug::write(std::ostream& out) const { 
    	cout << "TEST12345";
    }
    
    std::ostream& operator<<(std::ostream& out, const Fahrzeug* val) { 
        val->write(out); 
        return out; 
    }
    

    pkw.h

    #ifndef pkwHPP
    #define pkwHPP
    #include <string>
    #include "fahrzeug.hpp"
    
    class PKW : public Fahrzeug
    {
    	public:
    		PKW(char car_type[20],char plate[8],int age, int performance,int seat,bool child_carrier);
    		virtual ~PKW();
    
    		void set_child_carrier(bool x);
    		virtual void write (std::ostream& out)const;
    
    	private:
    		int seat;
    		bool child_carrier;
    };
    
    #endif
    

    pkw.cpp

    #include <iostream>
    #include <string>
    #include "pkw.hpp"
    
    using namespace std;
    
    PKW::PKW(char car_type[], char plate[],int age, int performance, int seat_in, bool child_carrier_in) 
    	: Fahrzeug(car_type,plate,age,performance)
    {
    	seat = seat_in;
    	child_carrier = child_carrier_in;
    }
    
    PKW::~PKW()
    {
    }
    
    void PKW::set_child_carrier(bool x){
    	child_carrier = x;
    }
    
    void PKW::write(std::ostream& out) const { 
        out << "Ein PKW der Marke: ";
    	int i=0;
    	while (car_type[i]!='\0') {
    		out << car_type[i];
    		i++;
    	}
    	out << "\nKennzeichen: ";
    	i=0;
    	while (plate[i]!='\0') {
    		out << plate[i];
    		i++;
    	}
    	out<<"\nBaujahr: "<<age<<"\nLeistung: "<<performance<<"\nSitze: "<<seat;
    	if (child_carrier) out<<"\nEs ist ein Kindersitz vorhanden";
    	else out<<"\nEs ist kein Kindersitz vorhanden";
    
    }
    

    main.cpp

    #include <iostream>
    #include <vector> 
    #include <string>
    #include "fahrzeug.hpp"
    #include "pkw.hpp"
    
    using namespace std;
    
    int main() {
        std::vector<Fahrzeug*> Fahrzeuge;
        Fahrzeuge.push_back(new PKW("OPEL","ABC",1980,75,5,true));
        Fahrzeuge.push_back(new PKW("VW","DEF",1990,90,5,false));
        Fahrzeuge.push_back(new PKW("VOLVO","GHI",1996,110,4,true));
    
        cout << "\n\n"<<Fahrzeuge.size()<<"\n\n";
        //< nicht <= !!!
        for (int i=0; i<Fahrzeuge.size();i++) 
            cout << Fahrzeuge[i] <<endl; 
        return 0;
    }
    

    mfg
    cu



  • SUUUPER - GANZ HERZLICHEN DANK !! 😃 😃

    Jetzt funktioniert es wie es soll - und gibt auch aus was es soll 👍 👍

    Ich habe nur noch eine einzige winzigkleine Frage, obwohl ich jetzt schon ein relativ schlechtes Gewissen habe 🙄

    Ich lege ja ein fixes Char-Array der Größe 20 an um die Typenbezeichnung einzulesen.
    Falls jemand mehr als diese 20 Stellen eingibt wird der String eben abgeschnitten und setze an die letzte Stelle ein '\0'.

    Falls aber jemand z.B. nur 5 Zeichen eingibt wird trotzdem an die 20ste Stelle das '\0' gesetzt - und ich bekomme je nach Vorbelegung des Speichers einen Haufen Mist in die Ausgabe.

    Lässt sich so ein Char-Array irgendwie einfach mit '\0' vorbelegen ?
    Oder je nach Länge der Eingabe irgendwie "abschneiden" ?

    char type [20];
    cin >> type;
    type[19]='\0';
    

    Ein glückliches Programmier-Mädel 😃



  • Nabend,

    das Array kann man z. B. mit der Funktion std::memset() mit 0en vorbelegen. Oder
    aber du machst es dir einfacher und nutzt std::string und musst dich um die
    Null-Terminierung nicht mehr kuemmern:

    #ifndef FUHRPARK_FAHRZEUG_H_INCLUDED
    #define FUHRPARK_FAHRZEUG_H_INCLUDED
    
    #include <string>
    
    class Fahrzeug
    {
        public:
            Fahrzeug(const std::string &car_type, const std::string& plate,int age, int performance);
            ~Fahrzeug();
    
            void change_plate(char plate[8]);
            void show_car();
            virtual void write (std::ostream& out)const;
    
            std::string car_type;
            std::string plate;
            int age;
            int performance;
    };
    

    In der .cpp-Datei dann entsprechend:

    Fahrzeug::Fahrzeug(string car_type_in, string plate_in,int age_in, int performance_in)
        : car_type(car_type_in), plate(plate_in), age(age_in), performance(performance_in) {
        cout << "Neues Fahrzeug eingestellt " << endl;
    }
    

    Nach dem ':' kommt hier die sogenannte Initialisierungsliste. Du sparst dir
    hiermit die Zuweisung im CTor-Body. Ausserdem geschieht die hier _vor_ dem
    CTor-Body.

    mfg
    v R


Anmelden zum Antworten