Lösungsvorschlag gesucht: Ist hier ein Template zu verwenden ?
-
Hallo,
ich habe eine Klassenstruktur
Vater -> Kind1
Vater -> Kind2die Kinder haben eine GetFunktion die ein Objekt einer Klasse zurückgeben
RetKlasse1 Kind1::getValue(); RetKlasse2 Kind2::getValue();ich hätte dies gern verallgemeinert,
und würde gern in der BasisKlasse eine Funktion deklarieren, die dies beschreibt.Zusätzlich würde ich gern ein Objekt zurückgeben und nicht einen Zeiger.
Also eine Lösung wie
void * Vater::getValue()wäre mir nicht so lieb,
es sei denn ihr überzeugt mich vom Gegenteil.
Ich würde mir gern irgendwelche Speicherlöcher ersparen, daher normale Objekterzeugung.Danke für Tips ?
-
Mach doch für den Rückgabetyp eine Basisklasse.
class RetBase { public: //.. Operationen auf abgeleitete Klassen ~RetBase (){} }; class RetKlasse1 : public RetBase { //.. }; class RetKlasse2 : public RetBase { //.. }; class Kind { public: RetBase* getValue(); };Dann hast du eine saubere Schnittstelle für die Ret-Klassen, die du dann um die Funktionalitäten halt noch erweitern musst.ζ
-
Danke Dir für den Tip, das ist eine Idee,
nur leider sind die Rückgabeklassen nicht von mir und eine Gemeinsame Schnittstelle/Vererbungshirarchie gibt es dort noch nicht.Könnte man elegant irgendwie eine erzeugen ?
-
Also wenn du die Klassen bearbeiten darfst, dann könntest du schon eine Hierarchie einbauen, aber von bereits bestehenden System rumzubasteln halte ich für heikel. Natürlich könntest du das ganze minimal machen und einfach von der gezeigten Klasse erben. Das sollte bereits gehen. Allerdings wirst du dann Probleme mit der Funktionalität der abgeleitenden Klassen haben (sofern die nicht zufälligerweise auf Polymorphie passen..).
Mit der Basisklasse kämst du auch um void Zeiger herum, aber du müsstest halt immernoch die Basisklassen Zeiger casten + noch irgendwie herausfinden können, welches Objekt denn jetzt überhaupt referenziert. (Was ja eigl. gegen den Sinn von Polymorphie ist, aber imo besser als void*).
-
Grundsätzlich sind Funktionstemplates eine Möglichkeit. Für die Verallgemeinerung müsstest du irgendwo den Rückgabetypen speichern. Entweder als
typedefin den Klassen selbst, oder ausserhalb, z.B. in einem Traits-Template wie hierreturn_type.template <typename Class> typename return_type<Class>::type getValue(const Class& obj) { return obj.getValue(); }Die Traitsklasse könnte so aussehen (besseren Namen als
return_typewählen):// Allgemeiner Fall, entweder nichts oder einen Default-Typ definieren template <typename T> struct return_type { typedef T type; // Default-Typ }; // Templatespezialisierung für konkreten Rückgabetypen template <> struct return_type<Kind1> { typedef Ret1 type; // konkreter Rückgabetyp für Kind1 };Um dir genauer helfen zu können, solltest genau sagen, was du brauchst. Am besten illustrierst du es zusätzlich an einem kleinen Stück Code.