{"id":36,"date":"2014-09-25T09:00:14","date_gmt":"2014-09-25T09:00:14","guid":{"rendered":"http:\/\/www.voidbred.com\/blog\/?p=36"},"modified":"2014-09-24T05:38:24","modified_gmt":"2014-09-24T05:38:24","slug":"smart-pointer-alternative-to-shared_ptr","status":"publish","type":"post","link":"http:\/\/www.voidbred.com\/blog\/2014\/09\/smart-pointer-alternative-to-shared_ptr\/","title":{"rendered":"Smart Pointer Alternative To shared_ptr"},"content":{"rendered":"<p>shared_ptr brings convenience to memory management but it also comes at a cost.\u00a0 It blocks the use of covariant return types.\u00a0 Also it makes interfacing with other environments difficult, for instance if you wanted to make a C wrapper around your C++ code.\u00a0 shared_ptr keeps an internal reference count of the object, but if we switch that around and put the reference count inside of the object we could choose when to use smart pointers without losing a consistent count.\u00a0 That way we can keep our interfaces clean of smart pointers, but use them internally to get their benefit.\u00a0 Without further ado I present refcountptr with the disclaimer that I wrote it for this post, I&#8217;ve only done minimal testing.<\/p>\n<h6>refcountptr:<\/h6>\n<pre class=\"lang:default decode:true \">#pragma once\r\n\r\ntemplate&lt;class T&gt; \r\nclass refcountptr\r\n{\r\npublic:\r\n    ~refcountptr() {\r\n        if (this-&gt;px) {\r\n            this-&gt;px-&gt;release();\r\n        }\r\n    }\r\n\r\n    refcountptr() \r\n        : px(0) {}\r\n\r\n    template&lt;class Y&gt;\r\n    explicit refcountptr( Y * p ): px( p )\r\n    {\r\n        if (this-&gt;px) {\r\n            this-&gt;px-&gt;retain();\r\n        }\r\n    }\r\n\r\n    template&lt;class Y&gt;\r\n    refcountptr( refcountptr&lt;Y&gt; const &amp; r )\r\n        : px( r.px )\r\n    {\r\n        if (px) {\r\n            this-&gt;px-&gt;retain();\r\n        }\r\n    }\r\n\r\n    refcountptr &amp; operator=( refcountptr const &amp; r ) \r\n    {\r\n        swap(r.px);\r\n        return *this;\r\n    }\r\n\r\n    template&lt;class Y&gt;\r\n    refcountptr &amp; operator=(refcountptr&lt;Y&gt; const &amp; r)\r\n    {\r\n        swap(r.px);\r\n        return *this;\r\n    }\r\n\r\n    T&amp; operator* () const {\r\n        return *px;\r\n    }\r\n\r\n    T * operator-&gt; () const {\r\n        return px;\r\n    }\r\n\r\n    T * get() const {\r\n        return px;\r\n    }\r\n\r\nprivate:\r\n    template&lt;class Y&gt;\r\n    void swap(Y* newPtr) {\r\n        T* oldPx = px;\r\n        px = newPtr;\r\n        if (px) {\r\n            px-&gt;retain();\r\n        }\r\n        if (oldPx) {\r\n            oldPx-&gt;release();\r\n        }\r\n    }\r\n\r\n    T * px;\r\n};\r\n<\/pre>\n<h6>\u00a0example of usage:<\/h6>\n<pre class=\"lang:default decode:true \">#include \"refcountptr.hpp\"\r\n#include &lt;iostream&gt;\r\n\r\nclass Foo\r\n{\r\npublic:\r\n    Foo(int x) : _refCount(0), _x(x) {}\r\n    ~Foo() { std::cout &lt;&lt; \"dealloc!\" &lt;&lt; std::endl; }\r\n    void retain() { _refCount += 1; }\r\n    void release() { \r\n        _refCount -= 1; \r\n        if (_refCount&lt;=0) {\r\n            delete this;\r\n        } \r\n    }\r\n    int getX() { return _x; }\r\nprivate:\r\n    int _refCount;\r\n    int _x;\r\n};\r\n\r\nint main(int argc, char *argv[])\r\n{\r\n    refcountptr&lt;Foo&gt; bar;\r\n    {\r\n        refcountptr&lt;Foo&gt; foo(new Foo(1234));\r\n        bar = foo;\r\n        std::cout &lt;&lt; foo-&gt;getX() &lt;&lt; std::endl;\r\n    }\r\n    std::cout &lt;&lt; bar-&gt;getX() &lt;&lt; std::endl;\r\n    return 0;\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>shared_ptr brings convenience to memory management but it also comes at a cost.\u00a0 It blocks the use of covariant return types.\u00a0 Also it makes interfacing with other environments difficult, for instance if you wanted to make a C wrapper around your C++ code.\u00a0 shared_ptr keeps an internal reference count of the object, but if we&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[7],"_links":{"self":[{"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/posts\/36"}],"collection":[{"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/comments?post=36"}],"version-history":[{"count":5,"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/posts\/36\/revisions"}],"predecessor-version":[{"id":51,"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/posts\/36\/revisions\/51"}],"wp:attachment":[{"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/media?parent=36"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/categories?post=36"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.voidbred.com\/blog\/wp-json\/wp\/v2\/tags?post=36"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}