Klassen & Vererbung Problem



  • manni66 schrieb:

    Die Info-Funktio soll nach der Aufgabenstellung wohl eher so aussehen:

    Stimmt, nur mir vitual und const.



  • cooky451 schrieb:

    manni66 schrieb:

    Die Info-Funktio soll nach der Aufgabenstellung wohl eher so aussehen:

    Stimmt, nur mir vitual und const.

    const: wenn die Basis const ist ja, sonst nein
    virtual: muss nur in der Basis vorhanden sein, in der abgeleiteten Klasse dient es der Übsersichtlichkeit



  • Wie meinst du das mit dem Konstruktor? Der Fehler ist nun weg, es erfolgt aber trotzdem keine Ausgabe

    soweit bin ich nun und ich hoffe die "uglynames" sind nun auch weniger ugly^^

    #include <iostream>
    using namespace std;
    
    class Katalog
    	{
    	protected:
    		string Verfasser;
    		string Titel;
    	public:
    
    		Katalog(string pVerfasser, string pTitel)
    		{
    			Verfasser = pVerfasser;
    			Titel = pTitel;
    		}
    
    		virtual void Info() const 
    		{
    			cout << Verfasser << endl;
    			cout << Titel << endl;
    		}
    
    	};
    
    class KatalogPGB : public Katalog
    	{
    	private:
    		string Koerperschaft;
    	public:
    		KatalogPGB (string pKoerperschaft) : Katalog(Verfasser, Titel)
    		{
    
    			Koerperschaft = pKoerperschaft;
    		}
    
    	};
    
    class KatalogBuch : public Katalog
    	{
    
    	private:
    		string ISBN;
    	public:
    		KatalogBuch(string pISBN) : Katalog(Verfasser,Titel)
    		{
    
    			ISBN = pISBN;
    		}
    
    	virtual void Info() {
    
    			Katalog::Info();
    	    	cout<<ISBN<<endl;
    		}
    
    	};
    
    int main () {
    	Katalog A1("Hans", "Hubert");
    	KatalogBuch K1("12345");
    
    	K1.Info();
    
    	/*Katalog* a= &K1; 
        a->Info(); */
    
    	return 0;
    }
    


  • Bitte, hier sind deine Hausaufgaben:

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Katalog
    {
    	string Verfasser;
    	string Titel;
    	public:
    	Katalog(string Verfasser, string Titel)
    		: Verfasser(Verfasser)
    		, Titel(Titel)
    	{}
    
    	virtual void Info() const
    	{
    		cout << "Verfasser: " << Verfasser << '\n';
    		cout << "Titel: " << Titel << '\n';
    	}
    };
    
    class KatalogPGB : public Katalog
    {
    	string Koerperschaft;
    public:
    	KatalogPGB(string Verfasser, string Titel, string Koerperschaft)
    		: Katalog(Verfasser, Titel)
    		, Koerperschaft(Koerperschaft)
    	{}
    
    	virtual void Info() const
    	{
    		Katalog::Info();
    		cout << "Koerperschaft: " << Koerperschaft << '\n';
    	}
    };
    
    class KatalogBuch : public Katalog
    {
    	string ISBN;
    public:
    	KatalogBuch(string Verfasser, string Titel, string ISBN)
    		: Katalog(Verfasser, Titel)
    		, ISBN(ISBN)
    	{}
    
    	virtual void Info() const
    	{
    		Katalog::Info();
    		cout << "ISBN: " << ISBN << '\n';
    	}
    };
    
    int main()
    {
    	KatalogBuch K1("Hans", "Hubert", "12345");  
    	Katalog* a= &K1;
    	a->Info();
    }
    


  • Hehe sind zwar keine Hausuafgaben, aber deine Version klappt. Danke schonmal.

    Aaaaallerdings:

    gebe ich in der main nun folgendes ein:

    int main () {
    
    	KatalogBuch K1("hubert","hans","12345");
    	KatalogBuch k2("Emma","Peter","43214");
    	Katalog* a= &K1; 
        a->Info();
    	Katalog* b=&k2;
    	b->Info();
    
    	return 0;
    

    Kriegen wir zwar Vor und Nachnamen, allerdings nicht die ISBN Nummern

    Edit: hat sich erledigt. Klappt.

    Eine Frage bleibt: wieso muss ich bei jedem Konstruktor der Unterklassen die alten parameter erneut hineinschreiben. Was hat das dann noch mit Vererbng zu tun? Weil wir doch über ":Katalog(Verfasser, Titel)" diese Parameter weitergeben?!



  • Ich hab auch mal eine Version gemacht.

    #include <iostream>
    
    class Katalog
    {
    private:
        std::string verfasser, titel;
    public:
        Katalog(const std::string& v, const std::string& t)
        : verfasser(v), titel(t) {}
        std::string VerfasserName() const { return verfasser; }
        std::string TitelName() const { return titel; }
        virtual std::string InfoString() const = 0; //Rein virtuell!
    };
    
    std::string Katalog::InfoString() const //Rein virtuelle Methoden muessen
    {                                       //ausserhalb der Klasse definiert werden.
        return verfasser + ": \"" + titel + "\"";
    }
    
    class KatalogBuch : public Katalog
    {
    private:
        std::string isbn;
    public:
        KatalogBuch(const std::string& v, const std::string& t,
                    const std::string& i)
        : Katalog(v, t), isbn(i) {}
        std::string Isbn() const { return isbn; }
        virtual std::string InfoString() const
        {
            return Katalog::InfoString() + " ISBN: " + isbn;
        }
    };
    
    class KatalogPGB : public Katalog
    {
    private:
        std::string koerperschaft;
    public:
        KatalogPGB(const std::string& v, const std::string& t,
                   const std::string& k)
        : Katalog(v, t), koerperschaft(k) {}
        std::string Koerperschaft() const { return koerperschaft; }
        virtual std::string InfoString() const
        {
            return Katalog::InfoString() + " Koerperschaft: " + koerperschaft;
        }
    };
    
    int main()
    {
        KatalogBuch k("Ich", "Irgendwas", "1234");
        std::cout << k.InfoString();
        return 0;
    }
    

    Geht doch alles.

    Edit: Sowas blödes, da war noch jemand scharf drauf ne Lösung zu machen. Kommt davon, wenn man sich so viel Zeit lässt und denkt, dass hier keiner Hausaufgaben für andere macht 😃
    Egal, haste gleich 2 Lösungen. Viel Spaß damit.



  • RuggedC schrieb:

    Eine Frage bleibt: wieso muss ich bei jedem Konstruktor der Unterklassen die alten parameter erneut hineinschreiben. Was hat das dann noch mit Vererbng zu tun? Weil wir doch über ":Katalog(Verfasser, Titel)" diese Parameter weitergeben?!

    Ist halt so. Die Basis wird normalerweise automatisch initialisiert, dafür muss aber ein Defaultkonstruktor verfügbar sein. Ist hier aber nicht der Fall, weshalb du die Basis selber intialisieren musst.



  • RuggedC schrieb:

    Eine Frage bleibt: wieso muss ich bei jedem Konstruktor der Unterklassen die alten parameter erneut hineinschreiben. Was hat das dann noch mit Vererbng zu tun? Weil wir doch über ":Katalog(Verfasser, Titel)" diese Parameter weitergeben?!

    Die Antwort innerhalb der Sprache ist: Weil es nicht anders geht. Jede Funktion ist eigenständig und bekommt genau die Parameter, die sie erwartet.
    Die Meta-Antwort ist: Die Parameter von den geerbten Typen zu übernehmen würde Funktionen nicht nur inkonsistent machen, sondern auch so etwas verhindern:

    struct A { A(int i); };
    struct B : public A { B() : A(42) {} };
    


  • arghonaut schrieb:

    RuggedC schrieb:

    Eine Frage bleibt: wieso muss ich bei jedem Konstruktor der Unterklassen die alten parameter erneut hineinschreiben. Was hat das dann noch mit Vererbng zu tun? Weil wir doch über ":Katalog(Verfasser, Titel)" diese Parameter weitergeben?!

    Ist halt so. Die Basis wird normalerweise automatisch initialisiert, dafür muss aber ein Defaultkonstruktor verfügbar sein. Ist hier aber nicht der Fall, weshalb du die Basis selber intialisieren musst.

    Ich hab mir das jetzt so gedacht, dass er an der stelle

    public: 
    		KatalogBuch(string Verfasser, string Titel, string ISBN) 
            : Katalog(Verfasser, Titel) 
            , ISBN(ISBN)
    

    einen "string Verfasser" und einen "string Titel" initialisiert, der dann aber quasi die "Werte" bzw den Inhalt aus der oberklasse erbt.



  • "Verfasser" und "Titel" (also die Parameter der KatalogBuch-Konstruktors) werden an der Stelle nicht initialisiert. Das geschieht noch bevor irgend ein Objekt initialisiert wird. Und "Werte vererben" geht sowieso nicht. Werte sind Zustände von Objekten, und Zustände kann man haben, aber nicht erben.
    Außerdem ist in C++ (und wahrscheinlich in vielen anderen OOP-Sprachen) jede Klasse für ihre Member selbst verantwortlich. Das ist ja eben das schöne dabei: KatalogBuch erbt von Katalog. Katalog erfüllt seinen Teil, in dem Fall "Verfasser" und "Name" verwalten. Der Katalog-Konstruktor nimmt Parameter entgegen und kümmert sich dann darum, dass mit diesen was sinnvolles angefangen wird.
    Und geerbt wird an der Stelle sowieso nicht. Das ist eine simple Definition einer Methode (wenn auch einer speziellen - einem Kostruktor). Und die Syntax ist halt mal so, wenn du einen bestimmten Konstruktor der Basisklasse aufrufen musst.


Anmelden zum Antworten