Smart Pointer
-
Hi,
ich habe langsam die Schnauze voll von dem Ewigen freigeben von Resourcen, und daher habe ich mir gedacht, dass ich mir SmartPointer bastele
Das habe ich jetzt so gemacht:#pragma once template<class C> class CSafeBase { private: CSafeBase(const CSafeBase&) { }; CSafeBase& operator=(const CSafeBase&) { }; protected: C m_Type; public: C& Get() { return m_Type; } const C& Get() const { return m_Type; } CSafeBase(C Type) { m_Type=Type; } virtual ~CSafeBase() { }; }; template<class C> class CSafe //DUMMY { }; template<> class CSafe<SC_HANDLE> : public CSafeBase<SC_HANDLE> { public: CSafe(SC_HANDLE pType) : CSafeBase(pType) { } ~CSafe() { CloseServiceHandle(m_Type); } }; //... weitere spezielle CSafe#s für andere Windows-Typen template<> class CSafe<void*> : public CSafeBase<void*> { private: bool m_bArray; public: CSafe(void* pType, const bool& bArray) : CSafeBase(pType) { m_bArray=bArray; } ~CSafe() { if(m_bArray) { delete[] m_Type; } else { delete m_Type; } } };ist dies so OK oder seht ihr Probleme?
Danke,
S.
-
Sieht schon recht gut aus, allerdings würde ich noch ein paar Verbesserungen vorschlagen:
a) übergibt' den bArray-Parameter an den CSave<void*>-Ctor besser per Wert (bool sind nicht so groß, daß du dort const Reference benötigst) und evt. mit Defaultwert.
b) Bau statt eines CSafe<void*> lieber eine partielle Spezialisierung template<typename T> CSafe<T*> auf.
c) du könntest auch noch die Vector-Operatoren (* und ->) überladen.
d) ich würde den CSafeBase-Copy-Ctor und Zuweisungsoperator lieber protected setzen und in CSafe eine eigene Variante definieren.
-
Danke

a. Versteh ich nicht?
b. Gemacht
c. Gemacht.
d. Das ist mir zu aufwendig. ich brauche die Klasse hauptsächlich für lokale Funktion, welche am Anfang verschiedene WinAPI-Handels erstellen... Da brauche ich die Zuweisung einfach nicht
-
a habe ich jetzt verstanden. ich lasse es aber so wie vorher, ab er mit defaultwert

-
Socker schrieb:
ist dies so OK oder seht ihr Probleme?
Nun ja; Es übersetzt nicht, weil SC_HANDLE und 'CloseServiceHandle( SC_HANDLE )' nicht definiert sind. Davon abgesehen kann man keinen 'allgemeinen Smart-Pointer' für z.B. ein int anlegen.
Warum nicht einfach die sehr schönen und praxis-erprobten Smart-Pointer von boost verwenden.
Dort kann man auch ein CloseServiceHandle mit einbauen. Etwa so:
#include <boost/shared_ptr.hpp> SC_HANDLE getHandleIrgendwoher(); typedef /*implementation depended*/ DEREF_SC_HANDLE; // bei windows-HANDLE wäre das z.B. void // ... boost::shared_ptr< DEREF_SC_HANDLE> hnd( getHandleIrgendwoher(), &CloseServiceHandle ); // Zugriff über hnd.get()bei Löschen der letzten Kopie von 'hnd' wird CloseServiceHandle gerufen.
Gruß
Werner
-
SC_HANDLE ist von der WindowsTreiberProgrammierung

Davon abgesehen kann man keinen 'allgemeinen Smart-Pointer' für z.B. ein int anlegen.
Wollte ich ja gar nicht. Eigentlich nur für Windows-Handles und für mit new oder new[] allokierte Speicherbreiche
Boost kenne ich nicht, wobei
boost::shared_ptr< DEREF_SC_HANDLE> hnd( getHandleIrgendwoher(), &CloseServiceHandle );mir schon zu lang ist

Safe<SC_HANDLE> Manager(getHandleIrgendwoher());ist doch viel schöner?
-
Socker schrieb:
a. Versteh ich nicht?
kurz: "CSafe(void* val,const bool& isarray)" ist Overkill - für eingebaute Typen ist "CSafe(void* val,bool isarray)" praktischer.
@WinAPI-Handles: Da solltest du eventuell auf eine Bibliothek wie MFC umsteigen, damit hättest du für jeden Handle-Typ eine passende Wrapper-Klasse.
(außerdem sind afaik die meisten HANDLE-Typen nur typedef's auf long, also kannst du deine CSafe-Klasse nicht getrennt für (z.B.) HWND und HDC spezialisieren)
-
nee, geht leider net. Bei der Treiberprogrammierung darf man das leider net

-
Socker schrieb:
SC_HANDLE ist von der WindowsTreiberProgrammierung

Davon abgesehen kann man keinen 'allgemeinen Smart-Pointer' für z.B. ein int anlegen.
Wollte ich ja gar nicht. Eigentlich nur für Windows-Handles und für mit new oder new[] allokierte Speicherbreiche
Klaro! hinter new steht doch immer ein Typ - z.B. int oder halt sowas wie MyClass. Und mit Deinem Code kannst Du kein
CSafe< MyClass > p( new MyClass ); // compiliert nichtschreiben, da es keine allgemeine Implementierung gibt. Die Variante mit void* ist nicht typsicher und bringt Unsicherheiten.
Socker schrieb:
Boost kenne ich nicht,
was nicht ist, kann ja werden
. C++ machen und boost nicht kennen ist - wie soll ich sagen - ist einfach indiskutabel; da fehlt einfach was.Socker schrieb:
wobei
boost::shared_ptr< DEREF_SC_HANDLE> hnd( getHandleIrgendwoher(), &CloseServiceHandle );mir schon zu lang ist

.. kürzer als Deine Klasse

Gruß
Weerner
-
class C { }; CSafe<C*> T(new C); //mit... template<class T> class CSafe<T*> : public CSafeBase<T*> { private: bool m_bArray; public: CSafe(T* pType, const bool& bArray=false) : CSafeBase(pType) { m_bArray=bArray; } ~CSafe() { if(m_Type) { if(m_bArray) { delete[] m_Type; } else { delete m_Type; } } } };Anyway, boost werde ich mir dann mal zu Gemüte führen
