Delete template type

I have a general class that looks something like this:

template <class T> class Example { private: T data; public: Example(): data(T()) Example(T typeData): data(typeData) ~Example() // ... }; 

I'm a little confused about how to implement a deconstructor for something like this. In particular, since T is of any type, it can be allocated on the stack (this is always the case for Example , created using a constructor with no arguments) or on the heap.

For example, if the client makes a type for T a int* and provides a pointer to dynamic memory, how do I know to call delete on data , and not if the client set the type to int ?

+5
source share
5 answers

The simplest answer: no. Do not try to invade the user and do what they cannot expect. Accept the same policy as standard containers: suppose T clears properly.

If the client code is written correctly, it will use RAII classes (such as smart pointers) to automatically and correctly manage memory and other resources. If this is not the case, you cannot hope to fix this in your vendor code.

Make your class work with std::unique_ptr and std::shared_ptr , as well as with any other custom RAII class, and let your clients manage it themselves. What if they want to keep pointers that are not authorized?

+7
source

You can use template specialization.

 template <class T> class Example { private: T data; public: Example() : data(T()) {} Example(T typeData): data(typeData) {} }; template <class T> class Example<T*> { private: T* data; public: Example() : data(nullptr){} Example(T* typeData): data(typeData) {} ~Example() { delete data; } }; int main() { Example<int> e; Example<int*> e2; return 0; } 
+2
source

You can simply not worry about it, as the standard library does. For example, if you create a vector of pointers, you are responsible for deleting them before you let the vector go out of scope. Then people can decide if they want to delete it at all (maybe this is a temporary sort, but something else belongs to the object). They can also use smart pointers so that the vector destroys the object through the destructor for the smart pointer.

In this case, less. You do not need to complicate anything. You do not need to support multiple versions of the template. Finally, the user of your template has more control ... and, of course, responsibility.

0
source

I suggest you use std::unique_ptr for T when you need Example to store a pointer to the owner. If T is a raw pointer, then it simply does not own it and should not delete it.

If you need Example initialize the pointer, highlight it for std::unique_ptr and call std::make_unique in the default constructor.

 template<typename T> class Example<std::unique_ptr<T>> { Example() : data{std::make_unique<T>()} {} /* rest of the class */ }; 

If you do this, you should not specialize your class for T* to make new , since you cannot initialize pointers without ownership. You should get it in the constructor and possibly turn off the default constructor for raw pointers if you don't want it to be null.

 template<typename T> class Example<T*> { Example() = delete; Example(T* data_) : data{data_} /* data is not an owning pointer. No need for a destructor */ /* rest of the class */ }; 

If you follow these rules, you should not have problems with memory management.

0
source

Use auxiliary memory template classes that can be selected by type. You do not need to duplicate your class using template specialization. You can write only one class.

 #include <type_traits> template<typename T> // primary template struct Releaser { template<typename V> void release( V v ) { } }; template<> // explicit specialization for T = std::true_type struct Releaser<std::true_type> { template<typename V> void release( V v ) { delete[] v; } }; template <class T> class Example { private: T data; public: Example(): data(T()) {} Example(T typeData): data(typeData) {} typedef typename std::is_pointer<T>::value_type isptr_type; ~Example() { Releaser< isptr_type >::release( data ); } }; 

But you need to know the new called form, so use delete or delete [].

0
source

Source: https://habr.com/ru/post/1242632/


All Articles