[template] virtual methods
-
wie kann man sowas bewerkstelligen:
class Connector{ public: template<typename ScaleModule> virtual void foo(const ScaleModule& scaler)=0; }; class ConnectorA : public Connector{ public: template<typename ScaleModule> virtual void foo(const ScaleModule& scaler) { ... scaler.foo(); ... } }; class ConnectorB : public Connector{ public: template<typename ScaleModule> virtual void foo(const ScaleModule& scaler) { ... scaler.scale(); ... } }; class ScaleModuleA{ public: void scale() {...} }; class ScaleModuleB{ public: void scale() {...} }; int main(){ ScaleModuleA scalerA; //ist normale klassenmember des Calculators ScaleModuleB scalerB; //ist normale klassenmember des Calculators Connector* pConnectorA = new ConnectorA; Connector* pConnectorB = new ConnectorB; pConnectorA->foo( scalerModulA ); pConnectorA->foo( scalerModulB ); pConnectorB->foo( scalerModulA ); pConnectorB->foo( scalerModulB ); return 0; }ohne die Klasse ScaleModule selbst abzuleiten?
das das Bsp nicht zu kompilieren ist, ist mir klar. aber ich bräuchtee diesbezüglich irgendeinen workaround...
-
ich versuche das problem zu konkretisieren.
Während einer Berechnung muss ich daten Sklaieren. Dies kann auf diverse Arten geschehen (--> verschiedene ScaleModule).
Dazu durchlaufe ich einen Vector, der Pointer auf Connector besitzt.
Wobei sich die eigentlichen Connector Implementierungen unterscheiden koennen (ConnectorA, ConnectorB).
Unabhängig vom Conenctor-Typ soll aber der gleiche Scaler zum Einsatz kommen. Diese Module sollen aus Performance-Gründen keine
gemeinsame Basisklasse besitzen, damit die MEthoden inline geschrieben werden koennen. Und zudem sollte die methode scale möglichst ein Funktionstemplate sein (denn die Hierachie des Codes läßt ein Klassentemplate des Connectors diesbezüglich nicht zu.
So hanz komme ich da leider nicht weiter.
-
Virtual und inline vertragen sich nicht besonders gut, wenn man sie so wie du kombiniert. Ich bin der Meinung, dass du auf keinen Fall am falschen Ende sparen solltest; mach das template weg und benutz normale Polymorphie. Ein guter Compiler wird dir die Funktionen inlinen, wenn er nur irgendwie kann. Vielleicht solltest du auf Funktionszeiger ausweichen:
class ConnectorB : public Connector{ public: virtual void foo(void (*scaler)()) { ... scaler(); ... } };
-
Ich verstehe nicht so ganz was du willst. Geht das etwas konkreter?
Was auf jeden Fall nicht geht ist "template" mit "virtual" zu mixen, also bei Memberfunktionen. Kann nicht gehen, denk mal drüber nach.
Wenn das ganze inline expandiert werden soll... wenn es recht wenige Scaler gibt kannst du einfach "foo" selbst für alle möglichen Scaler überladen, wovon dann eben alle Overloads virtual sind. Die Implementierung musst du ja nicht x-fach tippen, die kannst du ja dann in ein Template auslagern welches du nur x-fach instanzierst -- nur um "virtual" zu verwenden muss der Compiler genau wissen wie viele verschiedene "foo" es gibt, und wie deren Signature genau aussieht, und das geht eben nicht wenn "foo" ein Template ist.
z.B. so:
class AbstractDings { public: virtual void foo(Scaler1& s) = 0; virtual void foo(Scaler2& s) = 0; virtual void foo(Scaler3& s) = 0; virtual void foo(Scaler4& s) = 0; virtual void foo(Scaler5& s) = 0; virtual void foo(Scaler6& s) = 0; }; #define IMPLEMENT_ABSTRACT_DINGS(impl) \ virtual void foo(Scaler1& s) { impl(s); } \ virtual void foo(Scaler2& s) { impl(s); } \ virtual void foo(Scaler3& s) { impl(s); } \ virtual void foo(Scaler4& s) { impl(s); } \ virtual void foo(Scaler5& s) { impl(s); } \ virtual void foo(Scaler6& s) { impl(s); } \ // end IMPLEMENT_ABSTRACT_DINGS class DingsA : public AbstractDings { template<ScalerType> void foo_impl(ScalerType& s) { // ... // ... // ... // ... } IMPLEMENT_ABSTRACT_DINGS(foo_impl) }; class DingsB : public AbstractDings { template<ScalerType> void foo_impl(ScalerType& s) { // ... // ... // ... // ... } IMPLEMENT_ABSTRACT_DINGS(foo_impl) }; class DingsC : public AbstractDings { template<ScalerType> void foo_impl(ScalerType& s) { // ... // ... // ... // ... } IMPLEMENT_ABSTRACT_DINGS(foo_impl) };
-
ja, ich verstehe was ihr meint. das problem ist diesbezüglich einfach schwer zu beschreiben, denn es gibt viele connectoren und viele scaler... daher wird es doch sehr lästig alle methoden eizeln zu implementieren zumal diese sehr lang sind.
das virtual nicht bei template methode funktioieren kann ist mir natürlch klar... ich wollte ja nur die logik, die ich bräuchte aufzeigen.
werde mir das gesagt dnochmal durch den kopf gehen lassen. irgendwie muss es ja gehen. evtl mus sich einfach nur etwas umdenken und die sache anders angehen.
trotzdem danke erstmal