Reputation: 2736
I'm having a following example of class template:
template<class T>
class MyContainer{
public:
T* myArray;
int size;
MyContainer(int n) : size(n){
myArray = new T[n];
}
~MyContainer(){
delete[] myArray;
}
};
Is it possible to use smart pointers like unique_ptr or shared_ptr for myArray so I don't need to deallocate it in destructor? How?
Upvotes: 0
Views: 416
Reputation: 20041
Not only can you, but you really should. Programmers are often surprised to discover that if a constructor throws an exception (which is the recommended way to signal that an object can't be created for any reason), the destructor is not run, because there's no general way for the compiler to know which lines in the destructor correspond to which lines in the constructor.
On the other hand, any objects that have been created are destroyed because there is a general way to know which ones need to be destroyed. To put it another way, if your object had two raw pointers, and the first call to new
succeeded, but the second failed, the destructor wouldn't be run, and the first pointer would never be delete
d. But if your object had two smart pointers, and the first was constructed successfully and the second failed, the first smart pointer would be properly destroyed and you wouldn't have to worry about it.
Upvotes: 1
Reputation: 23793
Yes you can, and you really should :
template<class T>
class MyContainer{
public:
std::unique_ptr<T[]> myArray;
int size;
MyContainer(int n) : myArray(new T[n]), size(n) { }
};
int main() {
MyContainer<int> c(10);
}
Or if possible, pass the size as a template parameter :
template<class T, std::size_t N>
class MyContainer{
public:
std::unique_ptr<T[]> myArray;
int size = N;
MyContainer() : myArray(new T[N]) { }
};
int main() {
MyContainer<int, 10> c;
}
Or, if possible, just use std::vector<>
or std::array<>
Notes:
unsigned
(std::size_t
)Upvotes: 4
Reputation: 45654
template<class T>
class MyContainer{
public:
unique_ptr<T[]> myArray;
int size;
MyContainer(int n) : size(n), myArray(new T[n]) {}
};
The smart-pointer must use the array deallocator, otherwise it's UB, though in the case of trivial types probably the same code.
Take a look here for the whole std::unique_ptr
interface.
Upvotes: 2