I tried writing this class
#include <memory>
class ContainerUnique
{
public:
ContainerUnique(void);
~ContainerUnique(void);
private:
std::unique_ptr<UniqueElement> u;
};
Where UniqueElement is a POD class defined elsewhere. I now define the constructor body like this:
ContainerUnique::ContainerUnique(void)
{
auto tmp = new UniqueElement(1);
this->u(tmp); // u is a unique_ptr<UniqueElement>. Should this call compile?
}
And it complies without exceptions. Running the program I find that after the constructor of ContainerUnique
has been called, u
contains a null pointer.
Is this the intended behaviour? And what unique_ptr method am I actually calling?
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.
A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it.
It can be assigned: class owner { std::unique_ptr<someObject> owned; public: owner() { owned=std::unique_ptr<someObject>(new someObject()); } };
This is a known problem with VS2010's unique_ptr
. It publicly inherits from its deleter if it's empty as an optimization (empty base optimization). The downside to the public inheritance is that all members of the deleter also become available members of unique_ptr
, in this case its operator()(T*)
that deletes the pointer.
The bug is fixed in VS2012's library where the inheritance is changed to private.
You are calling default_delete< UniqueElement >::operator () ( UniqueElement* ptr )
, because uniqe_ptr derives from it (to benefit from empty base class optimization), and it deletes ptr
. It's not exactly intended behavior for you, although I don't think the standard forbids it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With