Reputation: 36896
shared_ptr<void>
is special in that it, by definiton, will invoke undefined behavior by calling delete
on a void*
.
So, why is there not a shared_ptr<void>
specialization which throws a compile error?
Upvotes: 6
Views: 1233
Reputation: 90422
shared_ptr<T>
is special in that it is by design allowed to hold a pointer to any pointer type which is convertible to T*
and will use the proper deleter without UB! This comes into play with shared_ptr<Base> p(new Derived);
scenarios, but also includes shared_ptr<void>
.
For example:
#include <boost/shared_ptr.hpp>
struct T {
T() { std::cout << "T()\n"; }
~T() { std::cout << "~T()\n"; }
};
int main() {
boost::shared_ptr<void> sp(new T);
}
produces the output:
$ ./test
T()
~T()
If you visit http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/shared_ptr.htm, scroll down to the assignment section to see the very thing being demonstrated. See http://www.boost.org/doc/libs/1_47_0/libs/smart_ptr/sp_techniques.html#pvoid for more details.
EDIT as noted by trinithis, it is UB if the pointer type passed into the constructor is a void *
pointer. Thanks for pointing that out!
Upvotes: 7
Reputation: 392931
Using shared_ptr to hold an arbitrary object
shared_ptr can act as a generic object pointer similar to void*. When a shared_ptr instance constructed as:
shared_ptr<void> pv(new X);
is destroyed, it will correctly dispose of the X object by executing ~X.
This propery can be used in much the same manner as a raw void* is used to temporarily strip type information from an object pointer. A shared_ptr can later be cast back to the correct type by using static_pointer_cast.
Upvotes: 8
Reputation: 272487
But it is valid, in many circumstances. Consider the following:
class T
{
public:
~T() { std::cout << "~T\n"; }
};
int main()
{
boost::shared_ptr<void> sp(new T);
}
In circumstances where you try to pass a genuine void *
into the shared_ptr
constructor, you should get a compile error.
Upvotes: 1
Reputation: 1
If your pointer was created via something like malloc
, you can make a shared_ptr<void, dtor>
, where the dtor
calls free
. This will result in defined behavior.
But then again, perhaps you want undefined behavior :D
Upvotes: 4