Wenn man über das Problem ein wenig nachdenkt, so kommt man zumindest auf vier unterschiedliche Lösungen:
- Die ekelhafte Lösung.
Man erstellt ein enum:Und macht dann einfach eine Verzweigung bei den zu implementierenden Funktionen:Code: Alles auswählen
enum MyTypeEnum { myAType, myBType };
Damit muss man nur noch homogene Typen speichern:Code: Alles auswählen
void MyItem::Print() { if(myType == myAType) cout << "MyItem - myA" << endl; else if(myType == myBType) cout << "MyItem - myB" << endl; }
Ich habe solchen Code oft genug gesehen; er ist so ekelhaft, dass diese Lösung schon einmal indiskutabel ist. ;)Code: Alles auswählen
list<MyItem> myList;
- Die Lösung ohne Indirektion.
Man spezialisiert einfach die Myitem-Klasse:Damit hält man homogene Listen vor, und zwar pro Typ eine:Code: Alles auswählen
template <class T> class MyItem { public: void Print(); }; template <> void MyItem<MyA>::Print() { cout << "MyItem - MyA" << endl; } template <> void MyItem<MyB>::Print() { cout << "MyItem - MyB" << endl; }
Das Einfügen kann man dann mittels Hilfsfunktionen auch ganz geschmeidig implementieren:Code: Alles auswählen
list<MyItem<MyA>> myAList; list<MyItem<MyB>> myBList;
Code: Alles auswählen
template <typename T> void MyItemList::AddItem(MyItem<T> theItem) { GetTypedList<T>().push_back(theItem); } template <> list<MyItem<MyA>> & MyItemList::GetTypedList() { return myAList; } template <> list<MyItem<MyB>> & MyItemList::GetTypedList() { return myBList; }
- Die Lösung mit Indirektion.
Man lässt alle Template-Spezialisierungen von einer gemeinsamen Basis-Klasse erben:Code: Alles auswählen
class MyItemBase { public: virtual void Print() = 0; };
Und hält eine homogene Liste von unique_ptrern:Code: Alles auswählen
template <class T> class MyItem : public MyItemBase { public: virtual void Print(); }; template <> void MyItem<MyA>::Print() { cout << "MyItem - MyA" << endl; } template <> void MyItem<MyB>::Print() { cout << "MyItem - MyB" << endl; }
Code: Alles auswählen
list<std::unique_ptr<MyItemBase>> myList;
- Man nehme boost::variant. Nicht von mir ausprobiert.
- Stinkt nach Fisch.
- Ist wohl am effizientesten, da es nur homogene Datentypen ohne Indirektionen und ohne virtuelle Funktionen hält.
- Benutzt Indirektion, braucht virtuelle Funktionen.
- Keine Ahnung. Habe noch nie damit Erfahrungen gemacht. Hat jemand von Euch schon einmal damit rumgespielt?