{"id":643,"date":"2017-07-06T13:32:13","date_gmt":"2017-07-06T13:32:13","guid":{"rendered":"http:\/\/www.max-sperling.bplaced.net\/?p=643"},"modified":"2024-02-16T11:18:17","modified_gmt":"2024-02-16T11:18:17","slug":"break-cyclic-references-c","status":"publish","type":"post","link":"http:\/\/www.max-sperling.bplaced.net\/?p=643","title":{"rendered":"Cyclic references (C++)"},"content":{"rendered":"<p><strong>Problem<\/strong><br \/>\nThe following code shows the problem of a cyclic reference with shared pointers. When leaving the main function the strong reference counters for A and B gets reduced by one. But because they still have a strong reference to each other that counters are not reaching zero. This means none of both destructors will be called.<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\n#include &lt;iostream&gt;\r\n#include &lt;memory&gt;\r\n\r\nclass B;\r\n\r\nclass A\r\n{\r\npublic:\r\n    void setup(std::shared_ptr&lt;B&gt; b) { m_b = b;}\r\n    ~A() { std::cout &lt;&lt; &quot;destr. A&quot; &lt;&lt; std::endl; }\r\n\r\nprivate:\r\n    std::shared_ptr&lt;B&gt; m_b;\r\n};\r\n\r\nclass B\r\n{\r\npublic:\r\n    void setup(std::shared_ptr&lt;A&gt; a) { m_a = a; }\r\n    ~B() { std::cout &lt;&lt; &quot;destr. B&quot; &lt;&lt; std::endl; }\r\n\r\nprivate:\r\n    std::shared_ptr&lt;A&gt; m_a;\r\n};\r\n\r\nint main()\r\n{\r\n    auto a = std::make_shared&lt;A&gt;();\r\n    auto b = std::make_shared&lt;B&gt;();\r\n\r\n    a-&gt;setup(b);\r\n    b-&gt;setup(a);\r\n\r\n    return 0;\r\n}\r\n<\/pre>\n<hr>\n<p><strong>Solution<\/strong><br \/>\nThe following modification isn&#8217;t creating a cyclic reference anymore. When leaving the main function the strong reference counter of A will reach zero this time, cause B has just a weak_ptr on it. As soon as A gets destructed the strong reference counter of B reaches also zero and B will be destructed as well.<\/p>\n<pre class=\"brush: cpp; gutter: false; title: ; notranslate\" title=\"\">\r\nclass B\r\n{\r\npublic:\r\n    void setup(std::weak_ptr&lt;A&gt; a) { m_a = a; }\r\n    ~B() { std::cout &lt;&lt; &quot;destr. B&quot; &lt;&lt; std::endl; }\r\n\r\nprivate:\r\n    std::weak_ptr&lt;A&gt; m_a;\r\n};\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Problem The following code shows the problem of a cyclic reference with shared pointers. When leaving the main function the<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false},"categories":[64],"tags":[],"_links":{"self":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/643"}],"collection":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=643"}],"version-history":[{"count":1,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/643\/revisions"}],"predecessor-version":[{"id":16762,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=\/wp\/v2\/posts\/643\/revisions\/16762"}],"wp:attachment":[{"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=643"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=643"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.max-sperling.bplaced.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=643"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}