clone()
-
Über den Präprozessor lässt sich einiges machen. Über 100 abgeleitete Klassen geben mir allerdings zu denken, da bist du möglicherweise schon weit von "elegant" entfernt...
-
jencas schrieb:
geschrieben werden. Gibt es da eine (möglichst elegante) Methode, sich den ganzen "Schreibkram" vom Hals zu halten?
Die Fi nicht von F sondern von einem Helpertemplate ableiten:
template<class Derived, class Base> struct Cloneable : public Base { virtual Base* clone() { return new Derived(*dynamic_cast<Derived*>(this)); } virtual ~Cloneable() = 0 {} //verhindern dass Cloneable direkt instantiiert wird }; class Fi : public Cloneable<Fi, F> { /* ... */ };
-
warum dynamic_cast?
-
volkard schrieb:
warum dynamic_cast?
stimmt, static_cast hätts auch getan...
PS: clone() sollte natürlich auch const sein...
-
Zur Erklärung:
Es handelt sich um Funktoren, also recht "kleine" Klassen, die parametergesteuert in einer Factory zusammengestellt und von dieser in einem Container zurückgeliefert werden. In der Regel enthalten diese Klassen also nur den operator() sowie die Methode zum Clonen. Insofern stellt das clone() schon einen "nicht unerheblichen Ballast" dar.
Dank @pumuckl: Dein Ansatz scheint genau das zu sein, was ich mir so vorgestellt habe.
-
Für Functoren scheint mir das allerdings der absolute Overkill zu sein. Bist du sicher dass du da ne Factory und dynamischen Polymorphismus mit dem ganze vtable-Overhead brauchst?
-
pumuckl schrieb:
Für Functoren scheint mir das allerdings der absolute Overkill zu sein. Bist du sicher dass du da ne Factory und dynamischen Polymorphismus mit dem ganze vtable-Overhead brauchst?
Ja. Mal kurz zusammengefasst: die Factory liefert in Abhängigkeit diverser Parameter, die aus Benutzer-konfigurierbaren Tabellen stammen, einen Container von Funktoren, der dann wiederum per STL-Algorithmen auf Container angewendet wird, die die von den Funktoren zu bearbeitenden Daten enthalten.
-
Hm. Ein alternativer Ansatz für so ein Szenario wäre evtl. folgender:
Du machst dir eine Tabelle der möglichen Funktionen, die so ein Funktor ausführen kann. Du hast eine einzige Funktor-Klasse statt der zig Funktor-Klassen, und die Funktor-Objekte enthalten lediglich einen Funktionspointer auf die Funktion, deren Verhalten sie annehmen sollen. Die Factory erzeugt dann immer einen Funktor und setzt dessen Pointer auf die entsprechende Funktion in der Tabele. Der op() des Funktor delegiert den Aufruf einfach an die Funktion in der Tabelle.
Das kopieren der Funktoren wird damit simpel, außerdem musst du die Funktoren nicht über Pointer herumreichen sondern kannst sie wie gewohnt als Objekte auf dem Stack behandeln.
-
pumuckl schrieb:
Hm. Ein alternativer Ansatz für so ein Szenario wäre evtl. folgender:
Du machst dir eine Tabelle der möglichen Funktionen, die so ein Funktor ausführen kann. Du hast eine einzige Funktor-Klasse statt der zig Funktor-Klassen, und die Funktor-Objekte enthalten lediglich einen Funktionspointer auf die Funktion, deren Verhalten sie annehmen sollen. Die Factory erzeugt dann immer einen Funktor und setzt dessen Pointer auf die entsprechende Funktion in der Tabele. Der op() des Funktor delegiert den Aufruf einfach an die Funktion in der Tabelle.
Das kopieren der Funktoren wird damit simpel, außerdem musst du die Funktoren nicht über Pointer herumreichen sondern kannst sie wie gewohnt als Objekte auf dem Stack behandeln.Muss ich mal überdenken. Zusätzliches Problem ist nämlich, dass es sich um ein komplexes Multithreading-System handelt, in welchem mehrere der von mir oben beschriebenen Operationen parallel ausgeführt werden. Weil die "Produktion" der Funktorcontainer nämlich recht "teuer" ist, werden diese gecached und Clone an den anforderneden Thread ausgeliefert.
-
pumuckl schrieb:
Hm. Ein alternativer Ansatz für so ein Szenario wäre evtl. folgender:
Du machst dir eine Tabelle der möglichen Funktionen, die so ein Funktor ausführen kann. Du hast eine einzige Funktor-Klasse statt der zig Funktor-Klassen, und die Funktor-Objekte enthalten lediglich einen Funktionspointer auf die Funktion, deren Verhalten sie annehmen sollen. Die Factory erzeugt dann immer einen Funktor und setzt dessen Pointer auf die entsprechende Funktion in der Tabele. Der op() des Funktor delegiert den Aufruf einfach an die Funktion in der Tabelle.
Das kopieren der Funktoren wird damit simpel, außerdem musst du die Funktoren nicht über Pointer herumreichen sondern kannst sie wie gewohnt als Objekte auf dem Stack behandeln.Nach langer Zeit, bin ich mal wieder dazu gekommen, mich noch einmal mit diesem Problem zu beschäftigen. Dein Vorschlag funktioniert in diesem Falle so leider nicht, da die Funktoren Membervariablen haben, die in unterschiedlichen Containern voneinander abweichende Werte haben können.