{"id":1369,"date":"2020-06-24T13:57:15","date_gmt":"2020-06-24T20:57:15","guid":{"rendered":"http:\/\/209.126.2.187\/?p=1369"},"modified":"2020-06-24T14:01:09","modified_gmt":"2020-06-24T21:01:09","slug":"pimpl-opaque-pointers","status":"publish","type":"post","link":"https:\/\/nanzhou.cc\/index.php\/2020\/06\/24\/pimpl-opaque-pointers\/","title":{"rendered":"Pimpl (Opaque Pointers)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>Pimpl is used to hide implementation details for library consumers. It hides headers, data members, as well as private functions. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"cpp\" class=\"language-cpp line-numbers\">\/\/ foo.h - header file\n#include &lt;memory>\nclass foo\n{\n  public:\n    foo();\n    ~foo(); \n    foo(foo&amp;&amp;);\n    foo&amp; operator=(foo&amp;&amp;);\n  private:\n    class impl;\n    std::unique_ptr&lt;impl> pimpl;\n};\n\/\/ foo.cpp - implementation file\nclass foo::impl\n{\n  public:\n    void do_internal_work()\n    {\n      internal_data = 5;\n    }\n  private:\n    int internal_data = 0;\n};\nfoo::foo()\n  : pimpl{std::make_unique&lt;impl>()}\n{\n  pimpl->do_internal_work();\n}\nfoo::~foo() = default;\nfoo::foo(foo&amp;&amp;) = default;\nfoo&amp; foo::operator=(foo&amp;&amp;) = default;<\/code><\/pre>\n\n\n\n<p>Note that <code>~foo()<\/code> has to be defined after <code>foo::impl<\/code> gets fulfilled. This is a requirement from <code>unique_ptr<\/code>: <\/p>\n\n\n\n<p><code>std::unique_ptr<\/code>&nbsp;may be constructed for an incomplete type&nbsp;<code>T<\/code>, such as to facilitate the use as a handle in the Pimpl idiom.&nbsp;<strong>If the default deleter is used,&nbsp;<code>T<\/code>&nbsp;must be complete at the point in code where the deleter is invoked, which happens in the destructor, move assignment operator, and reset member function of&nbsp;<code>std::unique_ptr<\/code><\/strong>. (Conversely,&nbsp;<code>std::shared_ptr<\/code>&nbsp;can&#8217;t be constructed from a raw pointer to incomplete type, but can be destroyed where&nbsp;<code>T<\/code>&nbsp;is incomplete).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary Pimpl is used to hide implementation details for library consumers. It hides headers, data members, as well as private functions. Note that ~foo() has to be defined after foo::impl gets fulfilled. This is a requirement from unique_ptr: std::unique_ptr&nbsp;may be constructed for an incomplete type&nbsp;T, such as to facilitate the use as a handle in&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[59,25],"tags":[],"class_list":["post-1369","post","type-post","status-publish","format-standard","hentry","category-ood","category-software-engineering"],"_links":{"self":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1369","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/comments?post=1369"}],"version-history":[{"count":2,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1369\/revisions"}],"predecessor-version":[{"id":1372,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/posts\/1369\/revisions\/1372"}],"wp:attachment":[{"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/media?parent=1369"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/categories?post=1369"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nanzhou.cc\/index.php\/wp-json\/wp\/v2\/tags?post=1369"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}