Professional C__ - Marc Gregoire [377]
// ... definition of Simple not shown for brevity
shared_ptr { auto ptr = make_shared return ptr; } int main() { shared_ptr return 0; } Code snippet from shared_ptr\shared_ptr_return_from_function.cpp This will be efficient because C++11 will automatically call std::move() on the return statement in the func() function, which will trigger the move semantics of the shared_ptr. The same happens if you would use unique_ptr instead of shared_ptr. The unique_ptr does not support the normal copy assignment operator and copy constructor, but it does support the move assignment operator and move constructor, and that is why you can return a unique_ptr from a function. Take the following unique_ptr assignments: unique_ptr unique_ptr unique_ptr The line defining p2 will not compile because it is trying to use the copy constructor, which is not available for unique_ptr. The definition of p3 is good because std::move() (defined in the There is one more class in C++11 that is related to the shared_ptr template; the weak_ptr. A weak_ptr can contain a reference to memory that is managed by a shared_ptr. The weak_ptr does not own the memory, so the shared_ptr is not prevented from deallocating the memory. A weak_ptr will not destroy the pointed to memory when it goes out of scope; however, it can be used to determine if the memory has been deallocated by the associated shared_ptr or not. The constructor of a weak_ptr requires a shared_ptr or another weak_ptr as argument. To get access to the pointer stored in the weak_ptr you need to convert it to a shared_ptr. There are two ways to do this: Use the lock() method on the weak_ptr instance, which will return a shared_ptr, or create a new shared_ptr instance and give the weak_ptr as argument to the shared_ptr constructor. The weak_ptr is a rather advanced feature of the C++11 smart pointers. It is rarely used and not further discussed in this book, but it is good to know its existence. Writing Your Own Smart Pointer Class It is highly recommended to use the standard shared_ptr or unique_ptr classes. However, sometimes you need some functionality not provided by these standard implementations, or your compiler might not yet support shared_ptr in which case you can implement your own reference-counted smart pointer. This section explains how you can implement your own reference-counted smart pointer. Chapter 18 provides an initial version of a smart pointer class called Pointer which is using operator overloading so the user can use the Pointer class just like a normal dumb pointer. This section enhances this Pointer class to include reference counting which is missing from the initial version. The Need for Reference Counting As a general concept, reference counting is the technique for keeping track of the number of instances of a class or particular object that are in use. A reference-counting smart pointer is one that keeps track of how many smart pointers have been built to refer to a single real pointer, or single object. This way, smart pointers can avoid double deletion. The double deletion problem is easy to provoke. Consider the following class, Nothing, which simply prints out messages when an object is created or destroyed: class Nothing { public: Nothing() { cout << "Nothing::Nothing()" << endl; } ~Nothing() { cout << "Nothing::~Nothing()" << endl; } }; Code snippet