Posts Tagged ‘Move semantics’

C++11: Using std::unique_ptr as a class member: initialization, move semantics and custom deleters

October 4, 2012 13 comments

Updated 23rd February 2013: Fixed typos in the code, incorrect use of const, clarified the use of the terms “initialization” and “assignment” to be semantically correct, corrected/clarified references to “constructor” and “assignment operator”, added an explanation of the default copy assignment operator and unique_ptr’s private copy constructor and copy assignment operator.

Updated 12th May 2013: Fixed a factual error regarding standard functions not working as custom deleters in all scenarios, fixed a factual error stating that std::shared_ptr doesn’t support custom deleters (it does), and corrected references to boost which should have referred to std. Expanded the custom deleter section with example cases of new’ing your own resource classes or fetching resources from an external API or factory function. Added text explaining the advantages of using the function object idiom for custom deleters.

The std::unique_ptr class is C++11’s replacement for the flawed std::auto_ptr smart pointer from C++03. std::unique_ptr provides single-ownership pointer semantics and is therefore especially useful when dealing with resource handles which should belong to a single object, and its custom deleter feature (which allows the call to delete to be replaced with an arbitrary function call when the object is destroyed, such as CloseHandle or IUnknown::Release) is great for ensuring resources are closed properly before their handles are freed.

I’m not going to explain how std::unique_ptr or move semantics work here – see the References section at the bottom for some introductory links – rather, I’m going to specifically look at how std::unique_ptr should be used in a non-copyable class (that is, one with a private, or – in C++ 11 – deleted, copy constructor), and specifically, how to make sure the resource is freed exactly and only once.

Read more…

%d bloggers like this: