Virtuelle Funktion geht nicht
-
Was funktioniert nicht? Was sind die Fehlermeldungen, die dir dein Compiler ausspuckt?
gruß
syntax
-
Zeig mal ein vollständiges (aber ansonsten auf ein Minimum reduziertes) Beispiel, an dem der Fehler zu sehen ist. Das Beispiel, dass du hier zeigst, ist einfach zu wenig um eine Vermutung anzustellen.
Falls dein Compiler das
overrideAttribut aus dem C++11-Standard schon unterstützt (GCC ab 4.7, Intel ab 12, Microsoft ab 11), dann kannst du damit auch sicherstellen, dass deine überschreibende Methode auch wirklich überschreibt und ansonsten eine Fehlermeldung erzeugt wird.edit: Was soll denn bitte an deinem zweiten Beispiel nicht funktionieren? Abgesehen davon nutzt du in dem Beispiel gar nicht aus, dass die Methode virtual ist. Kann es sein, dass du gar nicht richtig verstanden hast, was virtual bedeutet und wozu es gut ist?
Zum 2. Beispiel:b irgendwas; a *was_anderes = &irgendwas; was_anderes->Update(); // Gibt korrekt "Class B" aus.
-
Es ging darum,dass ich in einem DirectX 11 Buch gesehen habe ,dass einer Systemclasse kleinere classen wie Grafik/Sound ..blah hinzugefügt wurden und diese classen hatten alle virtuelle Render/Update funktionen damit sie automatisch mit dem Aufruf von Render/Update der Systemclass aufgerufen werden und man somit nicht immer Graphics->Update(); Sound->Update(); ... schreiben musste
-
Es soll z.B bei diesen Klassen die virtuelle methode neben der normalen auch noch ausgeführt werden.Da diese virtuell ist müsste sie ja bei der nicht virtuellen auch noch aufgerzufen werden.
#include <iostream> using namespace std; class a { public: virtual void Up() { cout << "Hi A"<< endl; } }; class b : public a { public : void Up() { cout << "Hi B" << endl; } }; int main() { b iwa; while(1) { iwa.Up(); } getchar(); return 0; }ich bekomme nur "Hi B" und nicht "Hi A"
-
Ob du in der abgeleiteten Klasse das virtual hinschreibst oder nicht, ist egal. Die Funktion ist trotzdem virtual. Der Übersicht wegen würde ich es deshalb immer dazuschreiben.
-
Ja nur bekomme ich kein Hi A ausgegeben sondern nur Hi B
-
Deswegen ja. Das soll so sein.
-
Bob Wolfskin schrieb:
ich bekomme nur "Hi B" und nicht "Hi A"
Genau so, wie es sein soll. Du hast da was mit dem
virtualin den falschen Hals bekommen.
-
Du hast virtual völlig falsch verstanden. Was du möchtest, ist aus b::Up() a::Up() aufzurufen, was ja kein Problem ist.
-
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
-
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..
-
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
