Template: Methode als Templateparameter angeben
-
Hallo,
weiß jmd von euch wie ich bei meinem Template den Destruktor generalisieren kann?
Ich möchte COM Objekte in den ScopedPtr packen können, die im Destructor abgebaut werden - durch den Aufruf "ptr->release() wie im Code dargestellt; gleichzeitig soll der Destruktor aber auch Objekte abbauen können, die beispielsweise ein "delete" benötigen.
Wie kann ein solcher zweiter Templateparameter aussehen?
template <typename T> class ScopedPtr { public: ScopedPtr(T* _ptr) : ptr(_ptr) {} private: ScopedPtr() : ptr(nullptr) {} ~ScopedPtr(); private: T* ptr = nullptr; }; template <typename T> ADelPtr<T>::~ADelPtr() { if (ptr) ptr->release(); }
BTW: Das Template ist nicht vollständig, sondern auf das notwendigste reduziert.
VG
Jens
-
Wieso verwendest du nicht unique_ptr? Er hat für diesen Zweck den Deleter-Typen (oder per Default std::default_delete).
-
Jodocus schrieb:
Wieso verwendest du nicht unique_ptr? Er hat für diesen Zweck den Deleter-Typen (oder per Default std::default_delete).
Das stimmt, dieser funktioniert aber nicht mit den COM Objekten.
-
Warum sollte er nicht?
Aus dem Kopf getippt, Fehler sind zur Übung.namespace detail { template<typename T> void release(T* ptr) { ptr->release(); } } template<typename T> using ReleasePtr = std::unique_ptr<T, void(*)(T*)>; template<typename T> ReleasePtr<T> makeReleasePtr(T* ptr) { return ReleasePtr(ptr, &detail::release<T>); } ReleasePtr<Foo> ptr = makeReleasePtr(createFoo()); ptr->bar();
-
Das verbraucht weniger Speicher und ist einfacher zu benutzen:
namespace detail { struct ReleaseDeleter { template<typename T> void operator()(T* ptr) const { ptr->release(); } }; } template<typename T> using ReleasePtr = std::unique_ptr<T, detail::ReleaseDeleter>; template<typename T> ReleasePtr<T> makeReleasePtr(T* ptr) { return ReleasePtr(ptr); } ReleasePtr<Foo> ptr = makeReleasePtr(createFoo()); ptr->bar();
-
Weniger Speicher? Ich denke, der unique_ptr legt da ein Objekt deines Deleters per Default Konstruktor an, ein bisschen Speicherverschwendung hast du wohl immer.
-
Ethon schrieb:
Weniger Speicher? Ich denke, der unique_ptr legt da ein Objekt deines Deleters per Default Konstruktor an, ein bisschen Speicherverschwendung hast du wohl immer.
Nein, das Objekt braucht durch Empty Base Optimization keinen zusätzlichen Platz.
Das ist übrigens einer der Gründe, warum
unique_ptr
einen Template-Parameter für den Deleter hat und nicht einfach einen Funktionszeiger benutzt. Der Default-Deleter mitdelete
ist auch einstruct
, kein Zeiger.
-
Noch ein Hinweis: Die C++-Bibliothek der Windows Runtime beinhaltet bereits einen Smart Pointer für COM-Objekte, der auch noch ein paar zusätzliche COM-spezfische Methoden kennt:
https://msdn.microsoft.com/en-us/library/br244983.aspx
Vielleicht hilft das weiter.