{"id":5074,"date":"2016-12-12T15:52:51","date_gmt":"2016-12-12T15:52:51","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/specialities-of-std-shared-ptr\/"},"modified":"2023-06-26T12:32:36","modified_gmt":"2023-06-26T12:32:36","slug":"specialities-of-std-shared-ptr","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/specialities-of-std-shared-ptr\/","title":{"rendered":"Specialities of std::shared_ptr"},"content":{"rendered":"<p>After I draw the big picture of a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/std-shared-ptr\">last post<\/a>, I want to present two special aspects of this smart pointer in this post. First, I show with <span style=\"font-family: courier new,courier;\">std::shared_from_this<\/span> how to create a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> from an object; second, I&#8217;m interested in the question to the answer: Should a function take a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by copy or by reference? The numbers are quite interesting.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<h2>std::shared_ptr from this<\/h2>\n<p>Thanks to <span style=\"font-family: courier new,courier;\">std::enable_shared_from_this<\/span>, you can create an object that returns a <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> from this. Therefore, the class of the objects has to be public derived from <span style=\"font-family: courier new,courier;\">std::enable_shared_from_this<\/span>. Now, you have the method <span style=\"font-family: courier new,courier;\">shared_from_this<\/span> available, which you can use to create <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> from this.<\/p>\n<p>The program shows the theory in practice.<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ enableShared.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;memory&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">ShareMe<\/span>: <span style=\"color: #0000ff;\">public<\/span> std::enable_shared_from_this&lt;ShareMe&gt;{\r\npublic:\r\n  std::shared_ptr&lt;ShareMe&gt; getShared(){\r\n    <span style=\"color: #0000ff;\">return<\/span> shared_from_this();\r\n  }\r\n};\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n  std::shared_ptr&lt;ShareMe&gt; shareMe(<span style=\"color: #0000ff;\">new<\/span> ShareMe);\r\n  std::shared_ptr&lt;ShareMe&gt; shareMe1= shareMe-&gt;getShared();\r\n  {\r\n    <span style=\"color: #0000ff;\">auto<\/span> shareMe2(shareMe1);\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"shareMe.use_count(): \"<\/span>  &lt;&lt; shareMe.use_count() &lt;&lt; std::endl;\r\n  }\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"shareMe.use_count(): \"<\/span>  &lt;&lt; shareMe.use_count() &lt;&lt; std::endl;\r\n  \r\n  shareMe1.reset();\r\n  \r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"shareMe.use_count(): \"<\/span>  &lt;&lt; shareMe.use_count() &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; std::endl;\r\n\r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The smart pointer <span style=\"font-family: courier new,courier;\">shareMe<\/span> (line 17) and it copies <span style=\"font-family: courier new,courier;\">shareMe1<\/span> (line 18) and <span style=\"font-family: courier new,courier;\">shareMe2<\/span> (line 20) reference the very same resource and increment and decrement the reference counter.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5068\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/enabledShared.png\" alt=\"enabledShared\" style=\"margin: 15px;\" width=\"397\" height=\"208\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/enabledShared.png 397w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/enabledShared-300x157.png 300w\" sizes=\"auto, (max-width: 397px) 100vw, 397px\" \/><\/p>\n<p>The call <span style=\"font-family: courier new,courier;\">shareMe-&gt;getShared()<\/span> in line 18 creates a new smart pointer. <span style=\"font-family: courier new,courier;\">getShared()<\/span> internally uses (line 9) the function <span style=\"font-family: courier new,courier;\">shared_from_this<\/span>.<\/p>\n<p>There is something very special about the class <span style=\"font-family: courier new,courier;\">ShareMe.<\/span><\/p>\n<h3>Curiously recurring template pattern&nbsp;<\/h3>\n<p><span style=\"font-family: courier new,courier;\">ShareMe<\/span> is the derived class and type argument (line 6) of the base class <span style=\"font-family: courier new,courier;\">std::enabled_shared_from_this<\/span>. This pattern is called CRTP, an abbreviation for <strong>C<\/strong>uriously <strong>R<\/strong>ecurring <strong>T<\/strong>emplate <strong>P<\/strong>attern. Obviously, there is no recursion because the base class methods will be instantiated when they are called. CRTP is an often-used idiom in C++ to implement static polymorphism. Unlike dynamic polymorphism with virtual run-time methods, static polymorphism occurs at compile time.<\/p>\n<p>But now, back to the <span style=\"font-family: courier new,courier;\">std::shared_ptr.<\/span><\/p>\n<\/p>\n<h2>std::shared_ptr as a function argument<\/h2>\n<p>Therefore, we are dealing with a quite interesting question. Should a function take its <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by a copy of by reference? But first. Why should you care? Does it matter if a function takes its <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by copy or reference? Under the hood, all is a reference. My definite answer is yes, and no. Semantically, it makes no difference. From the performance perspective, it makes a difference.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ refVersusCopySharedPtr.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;memory&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> byReference(std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;&amp; refPtr){\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"refPtr.use_count(): \"<\/span> &lt;&lt; refPtr.use_count() &lt;&lt; std::endl;\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> byCopy(std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; cpyPtr){\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"cpyPtr.use_count(): \"<\/span> &lt;&lt; cpyPtr.use_count() &lt;&lt; std::endl;\r\n}\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n    std::cout &lt;&lt;  std::endl;\r\n\r\n    <span style=\"color: #0000ff;\">auto<\/span> shrPtr= std::make_shared&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(2011);\r\n\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"shrPtr.use_count(): \"<\/span> &lt;&lt; shrPtr.use_count() &lt;&lt; std::endl;\r\n\r\n    byReference(shrPtr);\r\n    byCopy(shrPtr);\r\n    \r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"shrPtr.use_count(): \"<\/span> &lt;&lt; shrPtr.use_count() &lt;&lt; std::endl;\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The function <span style=\"font-family: courier new,courier;\">byReference<\/span> (line 6 &#8211; 8) and <span style=\"font-family: courier new,courier;\">byCopy<\/span> (line 10 &#8211; 12) takes their <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by reference and copy. The output of the program emphasizes the critical point.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5069\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/refVersusCopySharedPtr.png\" alt=\"refVersusCopySharedPtr\" style=\"margin: 15px;\" width=\"409\" height=\"218\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/refVersusCopySharedPtr.png 409w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/refVersusCopySharedPtr-300x160.png 300w\" sizes=\"auto, (max-width: 409px) 100vw, 409px\" \/><\/p>\n<p>The function byCopy takes its <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by copy. Therefore, the reference count increases in the function body to 2 and decreases to 1. The question is now. How expensive is the incrementing and decrementing of the reference counter? Because incrementing the reference counter is an atomic operation, I expect a measurable difference. To be precise. The incrementing of the reference counter is an atomic operation with <a href=\"https:\/\/www.modernescpp.com\/index.php\/relaxed-semantic\">relaxed semantics<\/a>; the decrementing is an atomic operation with <a href=\"https:\/\/www.modernescpp.com\/index.php\/acquire-release-semantic\">acquire-release semantics.<\/a><\/p>\n<p>Let&#8217;s have a look at the numbers.<\/p>\n<h3>Performance comparison<\/h3>\n<p>My Linux PC is more powerful than my Windows PC. Therefore, you must read the absolute numbers with a grain of salt. I use GCC 4.8 and Microsoft Visual Studio 15. Additionally, I translate the program with maximum and without optimization. At first, my small test program.<\/p>\n<p>In the test program, I hand over the <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> by reference and copying and using the <span style=\"font-family: courier new,courier;\">std::shared_ptr<\/span> to initialize another <span style=\"font-family: courier new,courier;\">std::shared_ptr.<\/span> This was the most straightforward scenario to cheat the optimizer. I invoke each function 100 million times.<\/p>\n<h4>The program<\/h4>\n<p>&nbsp;<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ performanceRefCopyShared.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;chrono&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;memory&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\nconstexpr <span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">long<\/span> mill= 100000000;\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> byReference(std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;&amp; refPtr){\r\n  <span style=\"color: #0000ff;\">volatile<\/span> <span style=\"color: #0000ff;\">auto<\/span> tmpPtr(refPtr);\r\n}\r\n\r\n<span style=\"color: #2b91af;\">void<\/span> byCopy(std::shared_ptr&lt;<span style=\"color: #2b91af;\">int<\/span>&gt; cpyPtr){\r\n  <span style=\"color: #0000ff;\">volatile<\/span> <span style=\"color: #0000ff;\">auto<\/span> tmpPtr(cpyPtr);\r\n}\r\n\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n    std::cout &lt;&lt;  std::endl;\r\n    \r\n    <span style=\"color: #0000ff;\">auto<\/span> shrPtr= std::make_shared&lt;<span style=\"color: #2b91af;\">int<\/span>&gt;(2011);\r\n   \r\n    <span style=\"color: #0000ff;\">auto<\/span> start = std::chrono::steady_clock::now();\r\n  \r\n    <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">long<\/span> i= 0; i &lt;= mill; ++i) byReference(shrPtr);    \r\n    \r\n    std::chrono::duration&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; dur= std::chrono::steady_clock::now() - start;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"by reference: \"<\/span> &lt;&lt; dur.count() &lt;&lt; <span style=\"color: #a31515;\">\" seconds\"<\/span> &lt;&lt; std::endl;\r\n    \r\n    start = std::chrono::steady_clock::now();\r\n    \r\n    <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #2b91af;\">long<\/span> <span style=\"color: #2b91af;\">long<\/span> i= 0; i&lt;= mill; ++i){\r\n        byCopy(shrPtr);\r\n    }\r\n    \r\n    dur= std::chrono::steady_clock::now() - start;\r\n    std::cout &lt;&lt; <span style=\"color: #a31515;\">\"by copy: \"<\/span> &lt;&lt; dur.count() &lt;&lt; <span style=\"color: #a31515;\">\" seconds\"<\/span> &lt;&lt; std::endl;\r\n    \r\n    std::cout &lt;&lt; std::endl;\r\n    \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>First, the program is without optimization.<\/p>\n<h4>Without optimization<\/h4>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5070\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performance.png\" alt=\"performance\" width=\"350\" height=\"178\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performance.png 395w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performance-300x153.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5071\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceWindows.PNG\" alt=\"performanceWindows\" width=\"400\" height=\"131\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceWindows.PNG 652w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceWindows-300x98.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>And now, the one with maximum optimization.<\/p>\n<h4>With maximum optimization<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5072\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimization.png\" alt=\"performanceOptimization\" width=\"350\" height=\"145\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimization.png 486w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimization-300x124.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5073\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimizationWindows.PNG\" alt=\"performanceOptimizationWindows\" width=\"400\" height=\"111\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimizationWindows.PNG 772w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimizationWindows-300x83.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/performanceOptimizationWindows-768x213.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<h3>My conclusion<\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5057\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2016\/12\/comparisonEng.png\" alt=\"comparisonEng\" width=\"503\" height=\"221\" style=\"margin: 15px;\" \/><\/p>\n<p>The raw numbers of the program performanceCopyShared.cpp speak a clear message.<\/p>\n<ul>\n<li>The <span style=\"font-family: courier new,courier;\">perReference<\/span> function is about two times faster than its pendant <span style=\"font-family: courier new,courier;\">perCopy, with<\/span> maximum optimization on Linux about five times faster.<\/li>\n<li>Maximum optimization gives Windows a performance boost of 3; on Linux by a factor of 30 &#8211; 80.<\/li>\n<li>The Windows application is without optimization faster than the Linux application. That&#8217;s interesting because my Windows PC is slower.<\/li>\n<\/ul>\n<h2>What&#8217;s next?<\/h2>\n<p>The classical issue of smart pointers using reference count is to have cyclic references. Therefore, <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span> comes to our rescue. I will have in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/std-weak-ptr\">next post <\/a>a closer look at <span style=\"font-family: courier new,courier;\">std::weak_ptr<\/span> and show you how to break cyclic references.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>After I draw the big picture of a std::shared_ptr in the last post, I want to present two special aspects of this smart pointer in this post. First, I show with std::shared_from_this how to create a std::shared_ptr from an object; second, I&#8217;m interested in the question to the answer: Should a function take a std::shared_ptr [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":5068,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[364],"tags":[498,400,399],"class_list":["post-5074","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-embedded","tag-memory","tag-shared_ptr","tag-smart-pointers"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5074","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=5074"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5074\/revisions"}],"predecessor-version":[{"id":6914,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5074\/revisions\/6914"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5068"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5074"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5074"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5074"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}