Design Problem
-
Moin,
ich habe folgende Problemstellung,
ich möchte einen Algorithmus implementieren, der bezüglich der Eingabeparameter variabel ist (->Templates ??).
Innerhalb dieses Algorithmus möchte ich dann Methoden aufrufen die abhängig vom Typ des Eingabeparameters eine jeweils andere Implmentierung aufweisen.wie kann ich dass realisieren?
Ich habe bisher versucht ala Schablonenmethode vorzugehen, dh:
Im Headerfile eine Templatefunktion die die Struktur des Algorithmus abbildet. Dann habe ich wie gesagt innerhalb des Algorithmus die Methodenaufrufe die Typabhängig sind und genau das ist das Problem da ich die in den erbenden Klassen nicht überschreiben kann. (ich hatte die versucht virtuell zu deklarieren geht aber schief wegen der Eingabeparameter)Wäre toll wenn mir da jemand eine Idee hätte???
Mfg
-
andere implementierung, aber selbe semantik?
schau dir mal die STL an -> so sachen wie zB std::sort()
vergiss abstrakte klassen und virtuelle funktionen.
-
-
@shadow of Mine:
wo kann ich mir das anschauen? Find da nichts?
-
Wie kann ich es schaffen, dass wenn ich in der abstrakten Klasse eine virtuelle nicht implmentierte Funktion habe, diese dann in zwei beerbten Klasse verschieden implementiere um sie dann aus einer Templatemethode aufzurufen und sich der Compiler dann abhängig vom Typ der im Template verwendet wird die richtige Implmentierung raussucht???
-
Sieht ein bisschen verrückt aus, aber meinst du sowas?
#include <iostream> class AlgoBase { public: void calc() { Step1(); Step2_TemplateMethod(); Step3(); } protected: virtual void Step2_TemplateMethod()=0; virtual ~AlgoBase() {} private: void Step1() {std::cout << "Step1" << std::endl;} void Step3() {std::cout << "Step3" << std::endl;} }; class Algo1 : public AlgoBase { virtual void Step2_TemplateMethod() {std::cout << "Step2 - Algo1" << std::endl;} }; class Algo2 : public AlgoBase { virtual void Step2_TemplateMethod() {std::cout << "Step2 - Algo2" << std::endl;} }; template <typename Alg1, typename Alg2, bool cond> struct Select { typedef Alg1 Algo; }; template <typename Alg1, typename Alg2> struct Select<Alg1, Alg2, false> { typedef Alg2 Algo; }; int main() { Select<Algo1, Algo2, (1==0)>::Algo a; a.calc(); }
-
mit einer partiellen template-spezialiserung?
-
#include <iostream> class AlgoBase { public: template <typename T> void calc() { Step1(); Step2_TemplateMethod(T); Step3(); } protected: virtual void Step2_TemplateMethod()=0; virtual ~AlgoBase() {} private: void Step1() {std::cout << "Step1" << std::endl;} void Step3() {std::cout << "Step3" << std::endl;} }; class Algo1 : public AlgoBase { void Step2_TemplateMethod( "Äpfel") { //do something } }; class Algo2 : public AlgoBase { void Step2_TemplateMethod( "Häuser") { //do something } };also ich möchte Step2_TemplateMethod in zwei Unterklassen jeweils für einen best Typ implmentieren und der AlgoBase soll dann mit eben abhg vom Typ die richtige Implmentierung wählen.
Klar was ich meine?
-
#include <iostream> class AlgoBase { public: template <typename T> void calc( T mytype) { Step1(); Step2_TemplateMethod(mytype); Step3(); } protected: virtual void Step2_TemplateMethod()=0; virtual ~AlgoBase() {} private: void Step1() {std::cout << "Step1" << std::endl;} void Step3() {std::cout << "Step3" << std::endl;} }; class Algo1 : public AlgoBase { void Step2_TemplateMethod( othertype1 ) { //do something } }; class Algo2 : public AlgoBase { void Step2_TemplateMethod( othertype2 ) { //do something } };
-
Willst du vielleicht AOP ??
-
Das wird nicht mit virtuellen Methoden und dem oben angesprochenen Design Pattern funktionieren. Für sowas benutzt man imho Overloading.
-
Durch mit Hinzufügen von Methoden:
template <typename T> struct Type2Type { typedef T type; }; struct Aepfel {}; struct Haeuser {}; class Algo { public: template <typename T> void calc() { Step1(); Step2(typename Type2Type<T>::type()); Step3(); } private: void Step1() {std::cout << "Step1" << std::endl;} void Step3() {std::cout << "Step3" << std::endl;} void Step2(Aepfel) { std::cout << "Aepfel" << std::endl; } void Step2(Haeuser) { std::cout << "Haeuser" << std::endl; } }; int main() { Algo a; a.calc<Aepfel>(); }
-
@Shade Of Mine: nee das meine ich nicht
-
@Aquae:
mir ist halt wichtig, dass die Methode Step2 nicht implmentiert wird, sondern das sie von abgeleiteten Klassen implementiert werden können!
.. wie mache ich das dann?
-
template <typename T1, typename T2, typename T3> struct Type2Type { typedef T1 type1; typedef T2 type2; typedef T3 type3; };... dann für mehrere Übergabeparameter?
Mfg
-
Hier mit Unterklassen. Trifft vielleicht eher, das was du wolltest?
template <typename T> class Algo { public: void calc() { Step1(); Step2(T()); Step3(); } protected: virtual ~Algo(){} virtual void Step2(T)=0; private: void Step1() {std::cout << "Step1" << std::endl;} void Step3() {std::cout << "Step3" << std::endl;} }; class AlgoInt : public Algo<int> { virtual void Step2(int) { std::cout << "Step2 - int" << std::endl; } }; int main() { AlgoInt a; a.calc(); }Edit: So gesehen, hast du allerdings dann für jeden Typ einen quasi eigenen Algorithmus, der sich nur in Step2 unterscheidet. Wahrscheinlich auch nicht so wünschenswert.
-
Oder noch eine Variante, die jetzt schon von Aquae gepostete wäre aber wohl vorzuziehen.
template<typename T> class Algorithm { void Compute() { // ... typeSpecific(); } void typeSpecific(); }; template<typename T> void Algorithm::typeSpecific() { // Standardverhalten, in diesem Fall ein Fehler throw std::runtime_error("Keine Spezialisierung für Template-Argument-Typ"); } // Die konkreten Typabhängigen Methoden werden als Spezialisierung implementiert template<> void Algorithm<int>::typeSpecific() { // Verhalten für int } template<> void Algorithm<float>::typeSpecific() { // Verhalten für float }
-
Wobei ich deine Variante als intuitiver ansehe

-
Schon Möglich. Du setzt aber Vererbung ein, was ja das eigentliche Verfahren ist, um Verhalten neu zu definieren. Die Absicht von Template-Spezialisierungen ist ja eher, das selbe Verhalten typabhängig (somit evtl. effizienter) zu implementieren.
Außerdem hat es mit den Spezialisierungen noch einen Nachteil: Wenn im Algorithmus sehr viele Methoden "austauschbar" sein sollen, hat man bei entsprechend vielen Typen sehr schnell hunderte Spezialisierungen.
-
Verrücktwerd .. schrieb:
@Shade Of Mine: nee das meine ich nicht
Der Code der hier produziert wird sieht aber ziemlich danach aus.
Magst du mal beschreiben was du eigentlich machen willst? Und zwar abstrakt?