Methoden in Vererbung



  • Also ich denke Skym0sh0 hat es schon gesagt: das heisst also wenn die Methode in der Oberklasse als virtual deklariert ist, dann muss Sie, wenn sie in der Unterklasse überschrieben werden soll neu deklariert werden, ansonsten nicht?...



  • Wenn du die Methode überschreiben willst, musst du sie in der Unterklasse deklarieren. Ob virtual oder nicht, ist egal.



  • Eigentlich ganz einfach:
    Wenn Du eine Methode in einer Klasse definieren willst, musst Du sie dort auch deklarieren!



  • Ok. Und wenn ich sie nicht überschreiben will dann brauch ich nicht nochmal deklarieren? Egal ob virtual in der Oberklasse oder nicht?



  • jenny.caros schrieb:

    Ok. Und wenn ich sie nicht überschreiben will dann brauch ich nicht nochmal deklarieren?

    Nein. Wieso auch? Ist doch schon in der Basisklasse deklariert.



  • Ein Spezialfall liegt vor, wenn Du eine überladene Methode überschreibst, das würde dann ohne weitere Massnahmen alle anderen Überladungen verbergen ...



  • Also ich finde, dass OP den Terminus richtig nutzt.

    Wenn man eine Methode in der Oberklasse deklariert in der Headerdatei, dann braucht man diese doch nicht nochmal in der headerdatei der Unterklasse zu deklarieren oder?

    Nur, wenn Überschreiben gewünscht ist.

    Und falls Sie in der Oberklasse mit virtual deklariert wurde dann kann man Sie doch in den Unterklassen verschieden definieren, oder?

    Wenn Du mit definieren implementieren meinst: Ja, dennoch ist Deklaration in der Unterklasse notwendig. Du kannst hingegen nicht den Rückgabetyp/Parametertypen ändern. Das wäre dann eben eine Funktionsüberladung, s. auch belli.

    class Oberklasse
    {
    public:
        void foo() {/* ... */}
        virtual void bar() {/* ... */}
    };
    
    class Unterklasse1 : public Oberklasse
    {
    };
    // Unterklasse1-Instanz enthält nun aufrufbare Methoden foo und bar
    
    void Unterklasse1::foo()
    {
        // Nein, so nicht! Deklaration notwendig, aber wäre wegen fehlendem virtual eh widersinnig
    }
    
    void Unterklasse1::bar()
    {
        // auch das geht nicht, Deklaration in Unterklasse1 fehlt
    }
    
    class Unterklasse2 : public Oberklasse
    {
    public:
        void foo(); // eigentlich unsinnig; Überschreiben geht ja nicht, aber syntaktisch ist Deklaration ok
        virtual void bar(); // notwendig, wenn bar überschrieben werden soll
    };
    
    void Unterklasse2::bar()
    {
        // Dafür ist Deklaration wie oben notwendig, ist jetzt also in Ordnung
    }
    


  • Eisflamme schrieb:

    Du kannst hingegen nicht den Rückgabetyp/Parametertypen ändern. Das wäre dann eben eine Funktionsüberladung, s. auch belli.

    Doch, das geht eben schon 😉

    Bsp:

    #include <iostream>
    #include <ctime>
    
    class Base
    {
    	int x;
    };
    
    class Derive : public Base
    {
    	int y;
    };
    
    // -----------------------------------------------------------------------
    
    class FooBase
    {
    protected:
    	Base * m_inst;
    
    public:
    	FooBase()
    		: m_inst(new Base)
    	{	}
    
    	virtual Base& getInst(Base & b)
    	{
    		return *this->m_inst;
    	}
    };
    
    class FooDerive : public FooBase
    {
    public:
    	FooDerive()
    	{
    		this->m_inst = new Derive;
    	}
    
    	virtual Derive& getInst(Derive& de)
    	{
    		Base * b = this->m_inst;
    		Derive * d = static_cast<Derive*>(b);
    		return *d;
    	}
    };
    
    int main()
    {
    	srand(time(0));
    	Base * pb = rand()%2 ? new Base : new Derive;
    
    	FooBase * pfb = rand()%2 ? new FooBase : new FooDerive;
    
    	Base & b = pfb->getInst(*pb);
    	Derive & d = static_cast<Derive&>(pfb->getInst(*pb));
    
    	return 0;
    }
    

    (Es geht nur um das Ändern der Methodenköpfe und nicht um das Speichermangement!)



  • Skym0sh0 schrieb:

    Eisflamme schrieb:

    Du kannst hingegen nicht den Rückgabetyp/Parametertypen ändern. Das wäre dann eben eine Funktionsüberladung, s. auch belli.

    Doch, das geht eben schon 😉

    was dann eine Funktionsüberladung ist. pb ist ein Pointer auf Base und somit wird immer FooBase::getInst aufgerufen (welche nicht in FooDerived überschrieben, sondern nur überladen ist).



  • Oh Shit, du hast Recht. Da hab ich mich vertan, weil das in Java irgendwie geht (irgendwie, ich habs nicht im Kopf)

    My Bad


Anmelden zum Antworten