In Template prüfen, ob Templatevariable ein Zeiger ist??



  • ...es ist nämlich so, dass ich in einer eigenen Template-Listenklasse eine Methode namens DoAutoDelete() einfügen möchte. Und wenn in der Liste Zeiger auf Objekte abgelegt wurden, sollen diese Objekte auf Benutzerwunsch von der Templateklasse beim Destruktoraufruf automatisch gelöscht werden.
    das ist der eigentliche Hintergrund meiner Fragerei



  • Versuch mal folgendes:

    template <typename T> inline void cleanup( T& t )  { }
    template <typename T> inline void cleanup( T*& t ) { delete t; } // delete (T*)0; ist harmlos
    
    template<class T>
    bool CMyFirstTemplate<T>::Insert(T Value)
    {
    
      //...verarbeite Value und wenn Value ein Zeiger auf ein Objekt ist,
      //möchte ich den Speicher freigeben
    
      //if(Value != NULL)
      //    delete Value;
      cleanup(Value);
    }
    


  • hallo finix,

    danke für den Vorschlag, ich hab's eingebaut und eigentlich hätte es funktionieren müssen, aber zur Laufzeit springt das Programm immer in die erste Variante also:

    template <typename T> inline void cleanup( T& t )  { }
    

    und NICHT in:

    template <typename T> inline void cleanup( T*& t ) { delete t; }
    

    ich habe die Funktionen nicht als "inline" eingebaut aber das spielt wohl nix zur Sache..



  • Ich weiß es klingt albern, aber was ist, wenn du die Template-Deklaration für den Pointer zeilenmäßig über das andere machst?



  • Ich würde es in eine Klasse verlagern, da sind die Regeln nach denen ausgewählt wird wesentlich klarer. Das sollte gehen:

    template <class T> struct cleaner
    {
        static void clean(T const&){}
    }
    
    template <class T> struct cleaner<T*>
    {
        static void clean(T* p){ delete p; }
    }
    
    template <class T> void clean(T const& t)
    {
        cleaner<T>::clean(t);
    }
    


  • Hatte deinen letzten Post nicht gesehen. In dem Fall stimme ich natürlich hustbaer zu:

    template <typename T>
    class default_cleanup_policy
    {
    public:
      void cleanup( T const& t ) { }
    
    protected:
      ~default_cleanup_policy() { }
    };
    
    template <typename T>
    class default_cleanup_policy<T*>
    {
    public:
      void cleanup( T const* t ) { if (auto_delete_) delete t; }
    
      bool auto_delete() const             { return auto_delete_; }
      void auto_delete( bool auto_delete ) { auto_delete_ = auto_delete; }
    
    protected:
       default_cleanup_policy() : auto_delete_(true) { }
      ~default_cleanup_policy() { }
    
    private:
      bool  auto_delete_;
    };
    
    template <
      typename T,
      class cleanup_policy = default_cleanup_policy<T>
    >
    struct my_first_template : public cleanup_policy
    {
      bool tnsert( T const& value )
      {
        //...verarbeite Value und wenn Value ein Zeiger auf ein Objekt ist,
        //möchte ich den Speicher freigeben
    
        cleanup(value);
      }
    }
    


  • hallo finix & hustbaer! ich danke euch für die Hilfe!!
    es funktioniert wunderbar!

    @finix:
    jetzt hab ich aber noch ein paar fragen,
    warum funktioniert das Ganze, wenn man's mit Hilfe der zwei cleanup_policy - Klassen macht, nicht aber wenn man einfach zwei Methoden
    a la

    void cleanup(T const& t) {}
    void cleanup(T const* t) { if(auto_delete) delete t; }
    

    in die Klasse implementiert ?!



  • @finix:

    die zweite Frage bezieht sich auf Zeile 12 in deinem Quelltext.
    Kannst du mir kurz erläutern, was das <T>* nach dem Klassennamen bewirkt bzw. was es für die Klasse bedeutet?



  • @finix:

    ich hab mir die zweite Frage mit dem <T>[\b] gerade selbst beantwortet 🙂
    das die Klasse mit dem <T
    > am Ende des Klassennamens ist eine explizite Spezialisierung der Klasse [b]default_cleanup_policy** für einen Zeigertyp von T.
    richtig?



  • @finix:

    ich hab mir die zweite Frage mit dem <T>* gerade selbst beantwortet 🙂
    das die Klasse mit dem <T*> am Ende des Klassennamens ist eine explizite Spezialisierung der Klasse default_cleanup_policy für einen Zeigertyp von T.
    richtig?


Anmelden zum Antworten