2016-06-07 2 views
0

Ich habe eine Frage. dieses Template-Klasse BetrachtenDestruktor der Vorlage Klasse mit Zeiger

template<class T> 
class nodo{ 
public: 
    T data; 
}; 

des Nehmen wir an, dass ich die destructor bin nicht neu zu definieren. Wenn wir annehmen, dass T = int ist, hebt der Standarddestruktor die Daten auf. Aber was passiert wenn T = int *? Wird nur der Zeiger aufgehoben oder das Objekt zugespitzt? In der Theorie nur der Zeiger.

Wie kann ich das Objekt aufheben? Wie kann ich am Ende den Destruktor einer Template-Klasse schreiben, die einen Template-Parameter hat, der ein Pointer sein könnte (und damit eine explizite Deallocation)?

+4

leicht zu beheben, machen 'T' statt' unique_ptr 'statt. Dann wird das zugespitzte Objekt automatisch zerstört – vu1p3n0x

+2

Es ist nicht anders als wenn du 'class nodo {public: int * data;}' gemacht hättest. – GManNickG

+0

@ vu1p3n0x, unique_ptr funktioniert auch wenn Daten kein Zeiger ist? – CodeBott

Antwort

2

Ihre beste Möglichkeit ist std::unique_ptr<int> oder std::shared_ptr<int> als Template-Argument zu verwenden, dh verwenden

nodo<std::unique_ptr<int>> n1; 

statt

nodo<int*> n1; 

Sie können versuchen, etwas wie:

// Noop deleter 
template <typename T> struct deleter 
{ 
    void operator()(T& ptr) {} 
}; 

// deleter that does something 
template <typename T> struct deleter<T*> 
{ 
    void operator()(T* ptr) { delete ptr; } 
}; 


template<class T> 
class nodo{ 
public: 
    using deleter_t = deleter<T>; 
    T data; 

    ~nodo() 
    { 
     deleter_t()(data); 
    } 
}; 

Aber dann müssen Sie sich Sorgen um eine andere Dose Würmer machen. Was passiert, wenn nodo kopiert oder einem anderen Objekt nodo zugewiesen wurde? Sie müssen sich um alle Probleme kümmern, die The Rule of Three und The Rule of Five relevant machen.

+0

Danke, aber es funktioniert auch wenn Daten kein Zeiger ist? – CodeBott

+1

@CodeBott, verwenden Sie 'nodo ' für Knoten vom Typ 'int'. Verwenden Sie 'nodo >' anstelle von 'node ', wenn die Knoten Zeiger halten sollen. –

+0

Es sieht sehr gut aus! Ich werde es versuchen, Thx – CodeBott

0

Was Sie brauchen, ist eine teilweise spezielle Vorlage für Zeigertypen:

template<typename T> class Test { 
    T val; 
public: 
    Test(T const &v) : val(v) {} 
}; 

// Specialize for pointers 
template<typename T> class Test<T*> { 
    T* val; 
public: 
    Test(T* v) : val(v) {} 
    ~Test() { delete val; } 
}; 
+0

Es sieht eine gute Lösung aus. Ich bin waing für andere Ideen. Danke – CodeBott

+0

Verbieten Sie zumindest das Kopieren der Klasse, wenn T ein Zeiger ist. Andernfalls haben Sie UB, wenn die Klasse jemals kopiert wird. –

Verwandte Themen