{"id":5361,"date":"2017-12-15T20:45:18","date_gmt":"2017-12-15T20:45:18","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-smart-pointers\/"},"modified":"2024-01-07T16:19:55","modified_gmt":"2024-01-07T16:19:55","slug":"c-core-guidelines-rules-to-smart-pointers","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-rules-to-smart-pointers\/","title":{"rendered":"C++ Core Guidelines: Rules for Smart Pointers"},"content":{"rendered":"<p>There were a lot of C++ experts who said that smart pointers were the essential feature of C++11. Today, I will write about smart pointers in C++.<\/p>\n<p><!--more--><\/p>\n<p>The C++ core guidelines have thirteen rules for smart pointers. Half of them deal with their owner semantics; half of them with the question: How should you pass a shared pointer to a function?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5359\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/12\/gold-513062_640.png\" alt=\"gold 513062 640\" width=\"640\" height=\"480\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/12\/gold-513062_640.png 640w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/12\/gold-513062_640-300x225.png 300w\" sizes=\"auto, (max-width: 640px) 100vw, 640px\" \/><\/p>\n<p>Here is an overview of the rules.<\/p>\n<ul style=\"margin-top: 0px; margin-bottom: 1rem; color: #515151; font-family: 'PT Sans',Helvetica,Arial,sans-serif; font-size: 20px; font-style: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; background-color: #ffffff;\">\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-owner\" style=\"color: #268bd2; text-decoration: none;\">R.20: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">unique_ptr<\/code>&nbsp;or&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">shared_ptr<\/code>&nbsp;to represent ownership<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-unique\" style=\"color: #268bd2; text-decoration: none;\">R.21: Prefer&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">unique_ptr<\/code>&nbsp;over&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">shared_ptr<\/code>&nbsp;unless you need to share ownership<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-make_shared\" style=\"color: #268bd2; text-decoration: none;\">R.22: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">make_shared()<\/code>&nbsp;to make&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">shared_ptr<\/code>s<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-make_unique\" style=\"color: #268bd2; text-decoration: none;\">R.23: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">make_unique()<\/code>&nbsp;to make&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">unique_ptr<\/code>s<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-weak_ptr\" style=\"color: #268bd2; text-decoration: none;\">R.24: Use&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">std::weak_ptr<\/code>&nbsp;to break cycles of&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">shared_ptr<\/code>s<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-smartptrparam\" style=\"color: #268bd2; text-decoration: none;\">R.30: Take smart pointers as parameters only to explicitly express lifetime semantics<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-smart\" style=\"color: #268bd2; text-decoration: none;\">R.31: If you have non-<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">std<\/code>&nbsp;smart pointers, follow the basic pattern from&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">std<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-uniqueptrparam\" style=\"color: #268bd2; text-decoration: none;\">R.32: Take a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">unique_ptr&lt;widget&gt;<\/code>&nbsp;parameter to express that a function assumes ownership of a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">widget<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-reseat\" style=\"color: #268bd2; text-decoration: none;\">R.33: Take a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">unique_ptr&lt;widget&gt;&amp;<\/code>&nbsp;parameter to express that a function reseats the&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">widget<\/code><\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-sharedptrparam-owner\" style=\"color: #268bd2; text-decoration: none;\">R.34: Take a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">shared_ptr&lt;widget&gt;<\/code>&nbsp;parameter to express that a function is part owner<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-sharedptrparam\" style=\"color: #268bd2; text-decoration: none;\">R.35: Take a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">shared_ptr&lt;widget&gt;&amp;<\/code>&nbsp;parameter to express that a function might reseat the shared pointer<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-sharedptrparam-const\" style=\"color: #268bd2; text-decoration: none;\">R.36: Take a&nbsp;<code class=\"highlighter-rouge no-highlight\" style=\"font-family: 'Roboto Mono',monospace; padding: 0.2em; font-size: 18px; background-color: #f9f9f9;\">const shared_ptr&lt;widget&gt;&amp;<\/code>&nbsp;parameter to express that it might retain a reference count to the object ???<\/a><\/li>\n<li><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-smartptrget\" style=\"color: #268bd2; text-decoration: none;\">R.37: Do not pass a pointer or reference obtained from an aliased smart pointer<\/a><\/li>\n<\/ul>\n<p>The first five rules (<strong>R.20 &#8211; R.24<\/strong>) are quite obvious. I have written a few posts about them. Let me paraphrase the rules and refer to my previous posts.<\/p>\n<p>A <span style=\"font-family: courier new,courier;\"><a href=\"https:\/\/www.modernescpp.com\/index.php\/std-unique-ptr\">std::unique_ptr<\/a> <\/span>is an exclusive owner of its resource; therefore, you can not copy it but only move it. In contrast, a <span style=\"font-family: courier new,courier;\"><a href=\"https:\/\/www.modernescpp.com\/index.php\/std-shared-ptr\">std::shared_pointer <\/a><\/span>shares ownership. If you copy or copy assign a shared pointer, the reference counter will automatically be increased; if you delete or reset a shared pointer, the reference counter will be decreased. If the reference counter becomes zero, the underlying resource will be deleted. Because of this management overhead, you should use a <span style=\"font-family: courier new,courier;\">std::unique_ptr<\/span>, if possible (<strong>R.21<\/strong>).<\/p>\n<p>This overhead becomes, in particular true if you create a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span>. Creating a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> requires the allocation of the resource and the reference counter, which is, in sum, quite an expensive job; therefore, you should use the factory function <span style=\"font-family: courier new,courier;\">std::make_shared <\/span>(<strong>R.22<\/strong>). <span style=\"font-family: courier new,courier;\">std::make_shared<\/span> makes only one allocation. This is a big performance improvement for <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span>. In comparison, in the post &#8220;<a href=\"https:\/\/www.modernescpp.com\/index.php\/memory-and-performance-overhead-of-smart-pointer\">Memory and Performance Overhead of Shared Pointers<\/a>&#8221; the differences between creating and deleting raw pointers and shared pointers including the factory functions <span style=\"font-family: courier new,courier;\">std::make_shared<\/span> and <span style=\"font-family: courier new,courier;\">std::make_unique<\/span>.<\/p>\n<p>There is an additional, vital reason to create an <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> with <span style=\"font-family: courier new,courier;\">std::make_shared<\/span>, and an <span style=\"font-family: courier new,courier;\">std::unique_ptr<\/span> with <span style=\"font-family: courier new,courier;\">std::make_unique<\/span>: no memory leak (<strong>R.22 and R.23<\/strong>). Using two invocations of <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> or <span style=\"font-family: courier new,courier;\">std::unique_ptr<\/span> in one expression can cause a memory leak if an exception happens. I was hoping you could read the details about this issue in my last post: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-allocating-and-deallocating\">C++ Core Guidelines: Rules for Allocating and Deallocating <\/a>(R.13). <span style=\"font-family: courier new,courier;\"><br \/><\/span><\/p>\n<p>A <span style=\"font-family: courier new,courier;\">std::weak_ptr i<\/span>s not a smart pointer. A <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span> is no owner and lends only the resource from its <span style=\"font-family: courier new,courier;\">std::shared_ptr.<\/span> Its interface is quite limited. Using the method lock on a <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span>, you can lift a <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span> to a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span>. Of course, you have a question: Why do we need a <span style=\"font-family: courier new,courier;\">std::weak_ptr?<\/span> A <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span> helps to break the cycles of <span style=\"font-family: courier new,courier;\">std::shared_ptr <\/span><strong>(R.24)<\/strong>. These cycles are the reason a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> will not automatically release its resource. Or to say it the other way around. If you have a cycle of shared pointers, you will have a memory leak. Read the details of <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span> and how you can use them to overcome memory leaks with <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> in my previous post <a href=\"https:\/\/www.modernescpp.com\/index.php\/std-weak-ptr\"><span style=\"font-family: courier new,courier;\">std::weak_ptr.<\/span><\/a><\/p>\n<p>Now I&#8217;m done with my summary of smart pointers. That is more or less general knowledge of smart pointers. This will not hold for the remaining rules. They deal with the question: How should you pass a shared pointer to a function?<\/p>\n<\/p>\n<h3><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rr-smartptrparam\" style=\"color: #268bd2; text-decoration: none;\">R.30: Take smart pointers as parameters only to explicitly express lifetime semantics<\/a><\/h3>\n<p>This rule is a little bit tricky. If you pass a smart pointer as a parameter to a function and you use this function only as the underlying resource of the smart pointer, you do something wrong. In this case, you should use a pointer or a reference as a function parameter because you don&#8217;t have the lifetime semantics of a smart pointer.<\/p>\n<p>Let me give you an example of a smart pointer&#8217;s quite sophisticated lifetime management.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f3f3; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0099ff; font-style: italic;\">\/\/ lifetimeSemantic.cpp<\/span>\r\n\r\n<span style=\"color: #009999;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #009999;\">#include &lt;memory&gt;<\/span>\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">asSmartPointerGood<\/span>(std<span style=\"color: #555555;\">::<\/span>shared_ptr<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&amp;<\/span> shr){\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"shr.use_count(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> shr.use_count() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (3)<\/span>\r\n  shr.reset(<span style=\"color: #006699; font-weight: bold;\">new<\/span> <span style=\"color: #007788; font-weight: bold;\">int<\/span>(<span style=\"color: #ff6600;\">2011<\/span>));                                          <span style=\"color: #0099ff; font-style: italic;\">\/\/ (5)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"shr.use_count(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> shr.use_count() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (4)<\/span>\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">void<\/span> <span style=\"color: #cc00ff;\">asSmartPointerBad<\/span>(std<span style=\"color: #555555;\">::<\/span>shared_ptr<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;&amp;<\/span> shr){\r\n  <span style=\"color: #0099ff; font-style: italic;\">\/\/ doSomethingWith(*shr);<\/span>\r\n  <span style=\"color: #555555;\">*<\/span>shr <span style=\"color: #555555;\">+=<\/span> <span style=\"color: #ff6600;\">19<\/span>;\r\n}\r\n\r\n<span style=\"color: #007788; font-weight: bold;\">int<\/span> <span style=\"color: #cc00ff;\">main<\/span>(){\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> firSha <span style=\"color: #555555;\">=<\/span> std<span style=\"color: #555555;\">::<\/span>make_shared<span style=\"color: #555555;\">&lt;<\/span><span style=\"color: #007788; font-weight: bold;\">int<\/span><span style=\"color: #555555;\">&gt;<\/span>(<span style=\"color: #ff6600;\">1998<\/span>);\r\n  <span style=\"color: #006699; font-weight: bold;\">auto<\/span> secSha <span style=\"color: #555555;\">=<\/span> firSha;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"firSha.use_count(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> firSha.use_count() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;  <span style=\"color: #0099ff; font-style: italic;\">\/\/ (1)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  asSmartPointerGood(firSha);                                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (2)<\/span>\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*firSha: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>firSha <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"firSha.use_count(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> firSha.use_count() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*secSha: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>secSha <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"secSha.use_count(): \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> secSha.use_count() <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  asSmartPointerBad(secSha);                                              <span style=\"color: #0099ff; font-style: italic;\">\/\/ (6)<\/span>\r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #cc3300;\">\"*secSha: \"<\/span> <span style=\"color: #555555;\">&lt;&lt;<\/span> <span style=\"color: #555555;\">*<\/span>secSha <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n  std<span style=\"color: #555555;\">::<\/span>cout <span style=\"color: #555555;\">&lt;&lt;<\/span> std<span style=\"color: #555555;\">::<\/span>endl;\r\n  \r\n}\r\n<\/pre>\n<\/div>\n<p>&nbsp;<\/p>\n<p>I will start with the excellent case for a <span style=\"font-family: courier new,courier;\">std::shared_ptr.<\/span> The reference counter in line (1) is two because I used the shared pointer<span style=\"font-family: courier new,courier;\"> firSha<\/span> to copy-initialized <span style=\"font-family: courier new,courier;\">secSha. <\/span>Let&#8217;s look closer at the invocation of the function <span style=\"font-family: courier new,courier;\">asSmartPointerGood<\/span> (2).&nbsp; First (3), the reference count of <span style=\"font-family: courier new,courier;\">shr<\/span> is 2 and then becomes 1 in line (4).&nbsp; What happened in line (5)? I reset <span style=\"font-family: courier new,courier;\">shr<\/span> to the new resource: <span style=\"font-family: courier new,courier;\">new int(2011).<\/span> Consequentially, the shared pointer <span style=\"font-family: courier new,courier;\">firSha<\/span> and s<span style=\"font-family: courier new,courier;\">ecSha<\/span> are immediately shared owners of different resources. You can observe the behavior in the screenshot.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5360\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/12\/lifetimeSemantic.png\" alt=\"lifetimeSemantic\" width=\"400\" height=\"323\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/12\/lifetimeSemantic.png 499w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/12\/lifetimeSemantic-300x243.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>If you invoke <span style=\"font-family: courier new,courier;\">reset<\/span> on a shared pointer, magic happens under the hood.<\/p>\n<ul>\n<li>If you invoke <span style=\"font-family: courier new,courier;\">reset<\/span> without an argument, the reference counter will be decreased by one.<\/li>\n<li>If you invoke <span style=\"font-family: courier new,courier;\">reset<\/span> with an argument and the reference counter was at least 2, you will get two independent shared pointer owning different resources. This is a kind of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Object_copying\">deep copy<\/a> of shared pointers.<\/li>\n<li>The resource will be released if you invoke reset with or without an argument and the reference counter becomes 0.<\/li>\n<\/ul>\n<p>This magic is not necessary if you are only interested in the underlying resource of the shared pointer; therefore, a pointer or a reference is the right parameter for the function <span style=\"font-family: courier new,courier;\">asSmartPointerBad<\/span> (6).<\/p>\n<h2>Further information<\/h2>\n<p>Look also at a recent post by Bartek F. about a situation where weak_ptr prevents full memory cleanup: <a href=\"http:\/\/www.bfilipek.com\/2017\/12\/weakptr-memory.html\">How a weak_ptr might prevent full memory cleanup of a managed object<\/a>.<\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>There are six rules left for passing smart pointers to functions. So you know what I will write about in my <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-passing-smart-pointer\">next post<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>There were a lot of C++ experts who said that smart pointers were the essential feature of C++11. Today, I will write about smart pointers in C++.<\/p>\n","protected":false},"author":21,"featured_media":5359,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[498,399],"class_list":["post-5361","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c","tag-memory","tag-smart-pointers"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5361","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5361"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5361\/revisions"}],"predecessor-version":[{"id":6847,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5361\/revisions\/6847"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5359"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5361"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5361"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5361"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}