Virtuelle Funktion geht nicht



  • Wie geht den das wenn ich von b::Up() a::Up() aufrufen will??
    Ich meine in dem DirectX 11 buch hat er das so gemacht ,dass das virtuelle methoden waren...



  • Bob Wolfskin schrieb:

    Wie geht den das wenn ich von b::Up() a::Up() aufrufen will??
    Ich meine in dem DirectX 11 buch hat er das so gemacht ,dass das virtuelle methoden waren...

    virtual ruft immer die nächste am konkreten Objekt definierte Implementierung auf, unabhängig ob du einen Basisklassenzeiger oder einen auf das Konkrete Objekt hast. Wenn du eine virtuelle Up-Methode in A hast, B davon ableitest und diese überschreibst, und davon ein C ableitest ohne diese Methode erneut zu überschreiben wird auf einen Objekt der Klasse B und C die virtuelle Methode von B, auf einem konkreten Objekt vom Typ A die von A aufgerufen, selbst wenn du alle Objekte über einen A-Zeiger ansprichst.

    Um die Implementierung einer anderen Klasse in der Hierachie zusätzlich aufzurufen musst du die Anweisung "a::Up();" in deine überschriebene "b::Up()" schreiben:

    b::Up()
    {
      a::Up();
    }
    

    Keine weitere "Magie" ist nötig 😉



  • Ja dann hätte ich ja das gleiche was ich nicht wollte.

    Ich möchte ja einfach jeder klasse meine timing klasse hinzufügen ,ohne etwas zu ändern.Deshalb dachte ich ,dass wenn die Timingklasse die gleiche funktion ("Update") hat ,wird sie auch aufgerufen.



  • Bob Wolfskin schrieb:

    Ja dann hätte ich ja das gleiche was ich nicht wollte.

    Ich möchte ja einfach jeder klasse meine timing klasse hinzufügen ,ohne etwas zu ändern.Deshalb dachte ich ,dass wenn die Timingklasse die gleiche funktion ("Update") hat ,wird sie auch aufgerufen.

    Dann bleibt dir noch das folgende Konstrukt:

    class Timing
    {
        protected:
            virtual Update_()
            {
            }
        public:
            void Update()
            {
               //...
               Update_();
            }
    }
    

    Eine nicht virtuelle Methode die noch zusätzliche Behandlungen durchführt und dann eine virtuelle aufruft.



  • Hab das jetzt so gemacht :

    class Timing 
    { 
      protected: 
        virtual void Update_() 
        { 
    		cout << "tighh" << endl;
        } 
        public: 
            void Update() 
            { 
               //... 
               Update_(); 
            } 
    };
    class b : public Timing
    {
    public :
    
    	void Update() { cout << "Hi B" << endl; }
    
    };
    
    int main()
    {
    	b* demo = new b();
    
    	while(1)
    	{
    	demo->Update();
    	}
    	getchar();
    	return 0;
    }
    

    Funktioniert immernoch nicht.Die Update() funktion in der Timing klasse wird immernoch nicht aufgerufen


  • Mod

    Man kann das schon erreichen, was du möchtest, zum Beispiel so (da braucht's noch nicht einmal virtual, alles zur Compilezeit wie von dir beschrieben ausgewertet):

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
      void update()
      {
        cout << "Class A" << endl;
      }
    };
    
    class B
    {
    public:
      void update()
      {
        cout << "Class B" << endl;
      }
    };
    
    template <typename ... T> class SuperUpdater;
    
    template <typename First, typename ... Rest> class SuperUpdater<First, Rest...>: public First, SuperUpdater<Rest...>
    {
    public:
      void update() 
      {
        First::update();
        SuperUpdater<Rest...>::update();
      }
    };
    
    template<typename T> class SuperUpdater<T>: public T
    {
    public:
      void update()
      {
        T::update();
      }
    };
    
    int main()
    {
      SuperUpdater<A, B> ab;
      ab.update();
      SuperUpdater<A> a;
      a.update();
      SuperUpdater<B> b;
      b.update();
    }
    

    Aber ich kann mir beim besten Willen nicht denken, dass ein Directx-Tutorial solch ein Monstrum bringt. Besonders da beim Microsoft-Compiler(den man ja in der der Regel für DirectX benutzen wird) die C++11-Unterstützung mWn noch nicht weit genug ist, um dies überhaupt zu compilieren.

    Oben habe ich schon angedeutet, dass virtual eine typische Laufzeittechnik ist. Daher: Du hast da bestimmt etwas falsch verstanden und die Updater registrieren sich zur Laufzeit bei einem anderen Objekt, welche diese dann aufruft.

    edit: Im Prinzip ist obiger Code nicht ganz korrekt, da Mehrdeutigkeiten bei Templaterekursion auftreten werden. Aber für ein Forenbeispielprogramm ist mir das gut genug. Wenn jemand Spaß hat, mag er das verbessern.



  • Jungs, wo ist der virtuelle dtor?



  • @Bob Wolfskin
    Und warum rufst du in der Update Methode von b nicht einfach die von Timing auf? Du musst doch eh im Moment der Deklaration wissen, von wem die Klasse erbt.



  • Werde ich wohl auch so machen..


  • Mod

    cvcv schrieb:

    Jungs, wo ist der virtuelle dtor?

    Der ist zusammen mit den Membern einen heben gegangen.



  • SeppJ schrieb:

    cvcv schrieb:

    Jungs, wo ist der virtuelle dtor?

    Der ist zusammen mit den Membern einen heben gegangen.

    Dann hoffen wir mal, dass sie gleichzeitig wieder zurück kommen, und nicht etwa der arme dtor hinterher hinkt 😉



  • cvcv schrieb:

    SeppJ schrieb:

    cvcv schrieb:

    Jungs, wo ist der virtuelle dtor?

    Der ist zusammen mit den Membern einen heben gegangen.

    Dann hoffen wir mal, dass sie gleichzeitig wieder zurück kommen, und nicht etwa der arme dtor hinterher hinkt 😉

    Weil der arme dtor nicht gewohnt ist so viel zu heben, wird er auch in die Notaufnahme gebracht 😮



  • Bob Wolfskin schrieb:

    Hab das jetzt so gemacht :

    Wer lesen kann ist klar im Vorteil.

    Du musst schon die virtuelle Methode überschreiben, nicht die nicht-virtuelle. Aufrufen tust du aber die nicht-virtuelle (der Basisklasse, die wiederum die virtuelle intern aufruft).

    In deinem Fall:

    class Timing 
    { 
      protected: 
        virtual void Update_() 
        { 
        } 
      public: 
        void Update() 
        { 
          cout << "Basisfunktionalität" << endl;
          Update_(); 
        }
    
        virtual ~Timing() {}
    };
    
    class b : public Timing
    {
      protected:
        void Update_() { cout << "Spezielle Funktionalität" << endl; }
    };
    
    int main()
    {
        Timing * demo = new b();
        demo->Update();
        delete demo;
    }
    

    Bob Wolfskin schrieb:

    Funktioniert immernoch nicht.Die Update() funktion in der Timing klasse wird immernoch nicht aufgerufen

    Logisch...

    Mein Ansatz ist hier ein anderer: Die Timing-Klasse bietet über Update eine Bsisfunktionalität an, und die interne virtuelle Methode Update_ dient den abgeleiteten Klassen für eine Ergänzung.

    Zeus schrieb:

    Weil der arme dtor nicht gewohnt ist so viel zu heben, wird er auch in die Notaufnahme gebracht 😮

    *Der kleine arme virtuelle dtor möchte in der Spielzeugabteilung abgeholt werden* 😉



  • Oha, er wurde gefunden!


Anmelden zum Antworten