I am playing with LibSDL and tried to use smart pointers for some of the objects created by the Library (i.E. SDL_CreateWindow returns a SDL_Window* which I would like to put into a std::shared_ptr). For the rest of the post I will simple refer to SDL_Window but the same applies to other SDL objects.
The SDL_Window structure in the SDL header is a forward declaration for a simple structure without a destructor (plain old data) but there is a function called SDL_DestroyWindow which destroyes the SDL_Window and frees the allocated memory.
I use the following code to declare and initialize my smart pointer:
I am sure the forward declaration is the problem because you cannot delete a forward declarated type. The compiler simply does not know if it has the call a destructor if it has not been declared.
But what I do not understand is why I get the warning if I supply a custom deleter. In this case the default delete (and therefor class destructor) should not be used by the shared_ptr template. If the last shared_ptr runs out of context it simply calls the provided custom deleter (which should know the full definition for the class it is deleting)
Thank you for your response, but it does not hit the mark.
However, I have found the problem (and the resolution) which I will explain in my next post.
I now know what is causing the "problem" and will explain it.
class MyIncompleteType; // forward declaration
std::shared_ptr<MyIncompleteType> y(myAllocate(), myFree);
y.reset(); // this works without warning (and calls myFree)
y = nullptr; // this gives me warning C4150
The second parameter to the shared_ptr constructor (myFree) is used to create a specialized a custom deleter template which calles myFree if the object pointed to by shared_ptr has to be deleted.
y.reset(); invokes the custom delimiter and sets the shared_ptr to empty (which is
y = nullptr; initialized the shared_ptr with a new pointer to an object uf MyIncompleteType which is actually nullptr, but a standard deleter is created which causes to C4150 warning because it would delete the object using 'delete' (which is not going to happen because the new pointer is nullptr).
So if you have to reset a shared_ptr of an incomplete type you simply have to use the reset() method.
Assigning a new value to the shared_ptr will also assign a new deleter and if you assign a nullptr it will be boxed and the shared_ptr created will use a default deleter which causes the warning C4150.