Funktionen bei Vererbung verstecken (grob: brauche funktion die static und virtual gleichzeitig ist)
-
Hallo Community
Ich mache eben wieder ganz krasse sachen. Genauer gesagt will ich von einer Basisklasse eine static funktion der Abgeleiteten Klasse ausführen.
Das ist blöd zu erklären, daher hba cih mal einen kurzen schnipsel zusammen gehackt:
Das DingDong Beispiel:
#include <iostream> using namespace std; class A { public: A(){}; virtual ~A(){}; void dingdong() { this->ding(); } static void ding() { std::cout << "A ding" << std::endl; } }; class B : public A { public: B(){}; ~B(){}; // ding() ist absichtlich "static" und muss auch static sein static void ding() { std::cout << "B ding" << std::endl; } }; int main() { B* Bobj = new B; Bobj->ding(); // Output: "B Ding" Bobj->dingdong(); // Output: "A Ding" , ich möchte jedoch "B Ding" return 0; }
-
Es geht eben nur eines von beiden: static oder virtual, aber nicht beides.
Warum muß denn dann die Methode static sein?
-
Hi
Ja mir ist klar das es kein "virtual static" gibt.
B::ding() bis deshlab static sein weil ich zwingend auf B::ding() zugreifen muss ohne B instanziert zu haben.Die einzige Möglichkeit die ich sehen wäre :
A::dingding() virtual zu setzen und mit B::dingdong zu überschreiben. Dabei kann ich mir A::ding() quasi sparen.
Jedoch würde in B::dingdong() in meinem zig tausend Bobj jedesmal gleich aussehen:
class B : public A { public: B(){}; ~B(){}; void dingdong() { ding(); } static void ding() { std::cout << "B ding" << std::endl; } };Ich hoffe auf einen genialen Kopf der einen Workaround oder ein pattern bringt an das ich noch nicht gedacht habt.
-
Okay es wird noch krasser!
Ich glaube ich hab einen Workaround, es wäre mir aber sehr recht wenn jemand etwas dazu sagen könnte:
Hier der Code:
#include <iostream> using namespace std; // Die Basis klasse class A { public: // Standard Constructor A() { pBding = NULL; }; // Alternativ Constructor der einen void funktions pointer haben möchte A( void (*pB)() ) { pBding = pB; }; // Destructor virtual ~A(){}; // DingDing führt die funtkion im function pointer aus // sofern dieser != NULL ist (wenn der Alternativ Constructor // benutzt wurde) void dingdong() { if (pBding != NULL) pBding(); } private: // Speicher für den Funktionspointer void (*pBding)(); }; // Die abgeleitete Klasse class B : public A { public: // Constructor der den Alternativ Constructor von A() anspricht // Könnte mir bitte jemand erklären was genau ich hier mache? B() : A(ding) {}; // Destructor ~B() {}; // Die Ding Funktion. Zwingend static!!! static void ding() { std::cout << "B ding" << std::endl; } }; int main() { A* Aobj = new A; Aobj->dingdong(); // Kein Output da fuktionspointer = NULL // static call B::ding(); // Output: "B Ding" B* Bobj = new B; // Direkter Call der Ding funktiuon der abgeleiteten klasse Bobj->ding(); // Output: "B Ding" // Call über die dingdong funktion der Basisklasse Bobj->dingdong(); // Output: "B Ding" return 0; }Wenn jemand sagen könnte ob das legal ist oder ich hier im Kafee wahn herum code wär ich enorm dankbar!
Grüße Bloop
-
Bloop schrieb:
Wenn jemand sagen könnte ob das legal ist
ja. Ob es sinnvoll ist, ist eine ganz andere Frage, und ohne Kenntnis des zugrunde liegenden Designproblems nicht zu beantworten.
-
Okay, ich hole aus:
Gebaut wird eine Plugin - PluginManager Architektur.
- Plugins (Class
sind von der Schnittstelle (in meinem Beispiel Class A) abgeleitet.
- Plugins werden über eine Schnittstelle angesprochen (Ansammlung virtueller funktionen in Class A)Dem PluginManager sind nur die in Class A abgebildeten funktionen bekannt.
Um ein Plugin im Pluginmanager verwenden zu können muss es instanziert werden (ein object aus B erzeugen). Bevor der Benutzer jedoch entscheidet welches Plugin er verwenden will, stellt der PluginManager eine Liste der verfügbaren Plugins zuammen (ausführen der static function "ding" in Class B).Dieser erste Zugriff auf static B::ding() wird an einer anderen stelle geregelt. Wichtig ist das es keiner Instanzierung des Plugins benötigt um die informationen welche B::ding() bereit stellt zu bekommen.
Ist das Plugin instanziert (Bobj) ist der zugriff auf B::ding() über die schnittstelle nicht möglich (Class A kennt kein ding()).
Da dieser zugriff jedoch benötigt wird gibt es dne besagten workaround mit dem funktionspointer.Grüße Bloop
-
Hi,
ich befürchte, Dein Problem wird sich nicht lösen lassen, weil in C++ Memberfunktionspointer anders gehandhabt werden als welche für freie Funktionen .... besonders: Zum Aufruf einer Memberfunktion brauchst Du eine Instanz.
Gruß,
Simon2.
-
Ich habe eine Instanz!
In dem moment wo ich B::dingdong() aufrufe, ist B instanziert.Mein Beispiel von oben funkioniert zu mindest mal. Es deckt alles ab was ich machen möchte:
-
ich hab meine static funktion ding
-
ich kann über die schnitt stellen klasse A auf ding zugreifen ohne overkill von virtuellen funkionen.
Nun überzeugt mich warum das bullshit ist!

-
-
Bloop schrieb:
Ich habe eine Instanz!
In dem moment wo ich B::dingdong() aufrufe, ist B instanziert.Wie kommst du denn darauf?
Bloop schrieb:
Nun überzeugt mich warum das bullshit ist!

Weil das hier eine Anforderung war?
Bloop schrieb:
Wichtig ist das es keiner Instanzierung des Plugins benötigt um die informationen welche B::ding() bereit stellt zu bekommen.
Ich sehe da so ein komisches "new B" in deinem Code.
-
Richtig! Irgendwie muss ich den schnipsel ja ausführbar machen.
Was ist denn an meinem "new B" komisch?
Wie soll ich denn darstellen dass der Zugriff auf die von A abgeleitete Klasse B funkioniert wenn ich B nicht instanziere?// Rufe ding() auf ohne B instanzieren zu müssen, damit punkt 1) abgedeckt B::ding(); // Output "B ding" // Erzeuge ein B B* Bobj = new B; // Call über die dingdong funktion der Basisklasse, damit punkt 2) abgedeckt Bobj->dingdong(); // Output "B ding"Ich brauche folgendes:
// Objekt vom Typ der Schnittstelle A mit der spezialisierung B erzeugen A* Aobj2 = new B; // Zugriff auf die static funktion B::ding() A->ding(); // Geht nicht! da ding() in A unbekannt // Zugriff über funkionspointer geht! Aobj2->dingdong(); // Output "B ding"Ich verstecke in diesem fall alle spezifischen funkionalitäten von B (was auch sinn der sache ist, zugegeben)
Ich baue mir einen (hoffentlich legalen) workaround für ein benötigtes "virutal static".
Es is Bullshit weil es eine Anforderung war? Bitte erkläre mit den Sinn dieses Satzes.
Vielen Dank
-
Hi,
also ich würde nicht die "PlugIns" (= Funktionalitäten) und deren Verwaltung (="Infoschnittstelle") sowieso nicht in dieselbe Klassenhierarchie packen.
Übrigens: Wenn Du nicht die Namen "ding" und "dingdong" verwendetest, wäre Allen viellecht klarer, was sie sein sollen ... es scheint, dass die beiden eigentlich nichts miteinander zu tun haben....
Nochmal eine Designfrage: Welche Klasse würde das 2. PlugIn repräsentieren ? A2 ? Und damit ein separates B2 ? ....
Gruß,
Simon2.
-
Hallo Simon
ding() und dingdong() sind die Funkionen welche ich in meinem oberen Beispiel verwende, daher wollte ich die terminologie nicht im laufe des threads verändern.
Ich versuche zu erklären:
ding() ist eine static funktion in class B (Abgeleitete Klasse) welche "B ding" in die Console schreibtdingdong() ist eine NON static funkion in class A (Basisklasse / Schnittstelle) welche den Zweck haben soll "B ding" in die Console zu schreiben. Und das ganze unter verwendung der static ding() von class B
Ein zweites (ntes) Plugin (oder: Funkionalität) wird in einer Klasse B2 (welche abgeleitet von A ist realisiert. Zugriff auf B2 ist über die Funkionen der Basisklasse (Schnittstelle) A gewährleistet.
Die Funkionalität und die infoschnittstelle befinden sich NICHT in der selben Klassenhierarchie! Der verwendete Codeschnipsel ist eine sehr stark vereinfachte Darstellung des Vorhabens eine static funkion über eine basisklasse anzusprechen.
-
Bloop schrieb:
Es is Bullshit weil es eine Anforderung war? Bitte erkläre mit den Sinn dieses Satzes.
Dein Workaround ist "Bullshit", weil er deine eigene Anforderung (dass es gehen muss, ohne dass ein B erzeugt werden muss) nicht erfüllt.
-
Bloop schrieb:
Hallo Simon
ding() und dingdong() sind die Funkionen welche ich in meinem oberen Beispiel verwende, daher wollte ich die terminologie nicht im laufe des threads verändern....
Das war mir schon klar - ich meinte ja auch, dass Du bereits in Deinem Beispiel anhand der Funktionsnamen klarmachen solltest, welche Aufgaben sie in diesem Design übernehmen sollen.
Bloop schrieb:
...
ding() ist eine static funktion in class B (Abgeleitete Klasse) welche "B ding" in die Console schreibtdingdong() ist eine NON static funkion in class A (Basisklasse / Schnittstelle) welche den Zweck haben soll "B ding" in die Console zu schreiben. Und das ganze unter verwendung der static ding() von class B
Ach wirklich ?

DEN Quellcode habe ich auch verstanden .... aber es hat so furchtbar wenig mit "Plugins" und "Verwaltung" zu tun, wenn man "ding" auf eine Konsole schreibt.In meinen Augen las es sich so:
- B::ding() repräsentiert eine "Abfragefunktion für das PlugIn" und
- A::dingdong() ist quasi die implementierte Funktionalität
Damit wäre B die "Verwaltungsschnittstelle von A".
Aber wie gesagt: Schreib das Beispiel doch einfach mal mit Namen, die ein wenig aufschlussreicher sind (tust Du bestimmt im "echten Leben", aber hier verstehe ich das auch besser).Gruß,
Simon2.
-
MFK schrieb:
Bloop schrieb:
Es is Bullshit weil es eine Anforderung war? Bitte erkläre mit den Sinn dieses Satzes.
Dein Workaround ist "Bullshit", weil er deine eigene Anforderung (dass es gehen muss, ohne dass ein B erzeugt werden muss) nicht erfüllt.
Ach ok. Welche Funkionalität genau erfüllt er denn nicht? Bitte um Aufklärung,habe ich etwas übersehen?
... aber es hat so furchtbar wenig mit "Plugins" und "Verwaltung" zu tun, wenn man "ding" auf eine Konsole schreibt.
Völlig richtig! Es hat absolut gar nix mit Plugins zu tun. Meine Kernfrage (und der Grund warum ich den Thread erstellt habe) war ob es eine möglichkeit gibt eine Funktion, die in einer abgeleiteten Klasse static ist über die Basisklasse aufzurufen. Hier reichen ding() und dingdong() aus.
Die Erklärung das es sich um eine Plugin architektur handeln wird, war die antwort auf den 2. Post im Forum.
camper schrieb:
ja. Ob es sinnvoll ist, ist eine ganz andere Frage, und ohne Kenntnis des zugrunde liegenden Designproblems nicht zu beantworten.