Lösungsvorschlag gesucht: Ist hier ein Template zu verwenden ?



  • Hallo,

    ich habe eine Klassenstruktur

    Vater -> Kind1
    Vater -> Kind2

    die 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 typedef in den Klassen selbst, oder ausserhalb, z.B. in einem Traits-Template wie hier return_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_type wä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.


Anmelden zum Antworten