15.x — Chapter 15 comprehensive review

A smart pointer class is a composition class that is designed to manage dynamically allocated memory, and ensure that memory gets deleted when the smart pointer object goes out of scope.

Copy semantics allow our classes to be copied. This is done primarily via the copy constructor and copy assignment operator.

Move semantics mean a class will transfer ownership of the object rather than making a copy. This is done primarily via the move constructor and move assignment operator.

std::auto_ptr is deprecated and should be avoided.

An r-value reference is a reference that is designed to be initialized with an r-value. An r-value reference is created using a double ampersand. It’s fine to write functions that take r-value reference parameters, but you should almost never return an r-value reference.

If we construct an object or do an assignment where the argument is an l-value, the only thing we can reasonably do is copy the l-value. We can’t assume it’s safe to alter the l-value, because it may be used again later in the program. If we have an expression “a = b”, we wouldn’t reasonably expect b to be changed in any way.

However, if we construct an object or do an assignment where the argument is an r-value, then we know that r-value is just a temporary object of some kind. Instead of copying it (which can be expensive), we can simply transfer its resources (which is cheap) to the object we’re constructing or assigning. This is safe to do because the temporary will be destroyed at the end of the expression anyway, so we know it will never be used again!

You can use the delete keyword to disable copy semantics for classes you create by deleting the copy constructor and copy assignment operator.

std::move allows you to treat an l-value as r-value. This is useful when we want to invoke move semantics instead of copy semantics on an l-value.

std::unique_ptr is the smart pointer class that you should probably be using. It manages a single non-shareable resource. std::make_unique() (in C++14) should be preferred to create new std::unique_ptr. std::unique_ptr disables copy semantics.

std::shared_ptr is the smart pointer class used when you need multiple objects accessing the same resource. The resource will not be destroyed until the last std::shared_ptr managing it is destroyed. std::make_shared() should be preferred to create new std::shared_ptr. With std::shared_ptr, copy semantics should be used to create additional std::shared_ptr pointing to the same object.

std::weak_ptr is the smart pointer class used when you need one or more objects with ability to view and access a resource managed by a std::shared_ptr, but unlike std::shared_ptr, std::weak_ptr is not considered when determining whether the resource should be destroyed.

Quiz time

1) Explain when you should use the following types of pointers.

1a) std::unique_ptr

Show Solution

1b) std::shared_ptr

Show Solution

1c) std::weak_ptr

Show Solution

1d) std::auto_ptr

Show Solution

2) Explain how r-values references enable move semantics.

Show Solution

3) What’s wrong with the following code? Update the programs to be best practices compliant.


Show Solution


Show Solution

16.1 -- The Standard Library
15.7 -- Circular dependency issues with std::shared_ptr, and std::weak_ptr

22 comments to 15.x — Chapter 15 comprehensive review

  • jerron

    is std::forward introduced somewhere in this tutorial?

  • Dants

    for question 3b, I don't understand why make_share is a better choice? Since we are passing in two separate smart pointers, each pointing to separate objects, wouldn't make_unique be better?

  • 3a:

  • Matthias

    In 3b you wrote:

    doSomething(std::shared_ptr<Something>(new Something), std::shared_ptr<Something>(new Something));
    If the constructor for Something throws an exception, one of the Somethings may not be deallocated properly.

    But: At the time "doSomething()" runs, both shared_ptrs are constructed and will deallocate properly at some point.
    The problem is that the compiler might choose to create both "new Something"s before storing them inside their shared_ptrs, making this essentially "tmp1 = new Something; tmp2 = new Something; tmp3 = shared_ptr(tmp1); tmp4 = shared_ptr(tmp2); doSomething(tmp3, tmp4). Then if the second "new Something" throws the first "new Something" will not be properly deallocated. Or, if the first "shared_ptr()" throws the second "new Something" will not be properly deallocated.

  • Rohit singh

    can i make a project using only c++

  • Rohit singh

    Sir can i make a project on completing this course from this site

  • Jujinko

    Hey Alex,

    I believe you are missing a ":" on the initial code for 3b) "std:shared_ptr<Something>(new Something)"

  • C++ Learner

    Hi Alex, what is the difference between make_shared and shared_ptr? they both create shared ptr, am I right?

  • Alan

    Great tutorial! I've been interested in learning some of this stuff, and the other articles I found on this topic were pretty confusing. But now I have a decent understanding of move semantics, r-value references, etc.

  • Aaron

    Hi Alex,
    Thanks for the great tutorial! Just want to know what's your plan for the next few updates(what topics will be covered/added and when(approximately)). Thank you.

    • Alex

      Right now I'm working on an index to make it easier to find specific topics. After that, I'll probably cover some miscellaneous topics. Then maybe some more stuff on containers.

      I don't have much time to write new stuff these days so I can't say when any of this is likely to show up.

  • Andrew

    I'm so glad this chapter is out! This is the best overview of move semantics and smart pointers I have read. Thank you!

  • Rom

    Why did you deleted chapters b.2-b.6? I was suppose to read it today :(

    • Alex

      Originally chapters b.2-b.6 covered C++11 material. That material has now been integrated into the primary lessons, making these chapters completely redundant. Chapter b.1 now serves as a guide to new functionality added in C++11, and has cross-references to where that material can be found within the primary lessons.

Leave a Comment

Put all code inside code tags: [code]your code here[/code]