{"id":2322,"date":"2017-08-04T05:28:11","date_gmt":"2017-08-03T21:28:11","guid":{"rendered":"https:\/\/www.csslayer.info\/wordpress\/?p=2322"},"modified":"2017-08-04T05:28:11","modified_gmt":"2017-08-03T21:28:11","slug":"a-small-trick-about-pimpl","status":"publish","type":"post","link":"https:\/\/www.csslayer.info\/wordpress\/linux\/a-small-trick-about-pimpl\/","title":{"rendered":"\u4e00\u4e2a\u5173\u4e8e Pimpl \u7684\u5c0f\u6280\u5de7"},"content":{"rendered":"<p>\u4f7f\u7528 <a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/pimpl\">Pimpl<\/a> \u5f88\u591a\u65f6\u5019\u662f\u5fc5\u987b\u7684\uff0cABI \u517c\u5bb9\u7684\u65f6\u5019\u57fa\u672c\u90fd\u8981\u9760\u5b83\u3002\u5728 C++ 11 \u5f53\u4e2d\uff0c\u901a\u8fc7 default member initializer \u53ef\u4ee5\u5b9e\u73b0\u5f88\u591a\u6709\u8da3\u7684\u6548\u679c\uff0c\u52a0\u4e0a\u5b8f\u7684\u8bdd\u5f88\u591a\u65f6\u5019\u53ef\u4ee5\u5229\u7528\u6765\u5b9e\u73b0 Metadata \u7684\u6548\u679c\uff0c\u4f8b\u5982\uff1a<\/p>\n<pre>#define PROPERTY(NAME) \\\r\n    Property NAME{this, #NAME};\r\n\r\nclass Registry {\r\n    friend class Property;\r\n    public:\r\n        int&amp; getValueByName(const std::string &amp;name) {\r\n            return *values_[name];\r\n        }\r\n    \r\n    protected:\r\n        void registerValue(const std::string name, int* value) {\r\n            values_[name] = value;\r\n        }\r\n        std::unordered_map&lt;std::string, int*&gt; values_;\r\n};\r\n\r\n\r\nclass Property {\r\npublic:\r\n    Property(Registry* r, const std::string&amp; name) {\r\n        r-&gt;registerValue(name, &amp;value_);\r\n    }\r\n    \r\n    operator int() { return value_; }\r\n    Property&amp; operator=(int v) { value_ = v; return *this; }\r\n    \r\nprivate:\r\n    int value_;\r\n};\r\n\r\nclass MyRegistry : public Registry {\r\npublic:\r\n    PROPERTY(a);\r\n    PROPERTY(b);\r\n};\r\n\r\nint main()\r\n{\r\n    MyRegistry r;\r\n    r.getValueByName(\"a\") = 1;\r\n    r.b = 2;\r\n    return r.a + r.getValueByName(\"b\");\r\n}\r\n\r\n<\/pre>\n<p>\u4f46\u662f\u5b9e\u9645\u4e0a\u8fd9\u8fd8\u662f\u9700\u8981\u5b9a\u4e49\u65b0\u7684 member\uff0c\u5982\u679c\u5c06\u6765\u6709\u4e86\u65b0\u7684 member \u5c31\u6ca1\u6cd5\u4fdd\u8bc1 Binary compatibility \u4e86\uff0c\u5047\u8bbe\u6211\u4eec\u8981\u628a MyRegistry \u8f6c\u53d8\u6210 Pimpl \u600e\u4e48\u529e\u5462\uff1f\u7b80\u5355\u5b9e\u73b0\u4e00\u4e0b\u7684\u8bdd\u5c31\u4f1a\u53d8\u6210\u8fd9\u6837\uff1a<\/p>\n<pre>class MyRegistryPrivate {\r\n    Property a{???, \"a\"};\r\n};<\/pre>\n<p>\u90a3\u4e48 ??? \u5904\u4f20\u4ec0\u4e48\u624d\u597d\u5462\uff1f<\/p>\n<p>\u4f60\u53ef\u80fd\u4f1a\u60f3\u5230\u628a MyRegistry \u7684 pointer \u4f20\u7ed9 Pimpl \u4e0d\u5c31\u884c\u4e86\u5417\uff1f\u4f46\u662f\u4e0d\u8981\u5fd8\u4e86\uff0c\u6211\u4eec\u8fd8\u4f9d\u65e7\u5e0c\u671b\u901a\u8fc7 default member initializer \u7684\u5f62\u5f0f\u6765\u5b9a\u4e49\u3002\u4f20\u8fc7\u6765\u7684\u53c2\u6570\u4e4b\u540e\u5373\u4f7f\u76f4\u63a5\u53bb initialize\uff0c\u4e5f\u662f\u5728 default member initializer \u4e4b\u540e\u624d\u8fdb\u884c\u4e86\u3002\u4e5f\u5c31\u662f\u8bf4\u8fd9\u6837\u662f\u4e0d\u884c\u7684\uff1a<\/p>\n<pre>class MyRegistryPrivate {\r\n    public:\r\n        MyRegistryPrivate(MyRegistry *q) : q_ptr(q) {}\r\n\r\n        MyRegistry *q_ptr;\r\n        Property a{q_ptr, \"a\"};\r\n};<\/pre>\n<p>\u4e5f\u5c31\u662f\u8bf4\u8981\u4fdd\u8bc1\u5728\u66f4\u65e9\u7684\u65f6\u5019\u521d\u59cb\u5316 q_ptr\uff0c\u53ef\u4ee5\u7528\u4e00\u5c42\u7ee7\u627f\u6765\u4fdd\u8bc1\u8fd9\u70b9\u3002<\/p>\n<pre>template\r\nclass QPtrInit {\r\npublic:\r\n    QPtrInit(T *q) : q_ptr(q) { }\r\n    \r\nprotected:\r\n    T* q_ptr;\r\n};\r\n\r\nclass MyRegistryPrivate;\r\n\r\n#define PROPERTY_PRIVATE(NAME) \\\r\n    Property NAME{q_ptr, #NAME};\r\n\r\nclass MyRegistryPrivate : QPtrInit {\r\n    public:\r\n        MyRegistryPrivate(MyRegistry* q) : QPtrInit(q) {}\r\n        \r\n        PROPERTY_PRIVATE(a);\r\n        PROPERTY_PRIVATE(b);\r\n};\r\n<\/pre>\n<p>\u5b8c\u6574\u4f8b\u5b50\u53c2\u89c1\uff1a<a href=\"http:\/\/cpp.sh\/4bhvh\">http:\/\/cpp.sh\/4bhvh<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4f7f\u7528 Pimpl \u5f88\u591a\u65f6\u5019\u662f\u5fc5\u987b\u7684\uff0cABI \u517c\u5bb9\u7684\u65f6\u5019\u57fa\u672c\u90fd\u8981\u9760\u5b83\u3002\u5728 C++ 11 \u5f53\u4e2d\uff0c\u901a\u8fc7 default member initializer \u53ef\u4ee5\u5b9e\u73b0\u5f88\u591a\u6709\u8da3\u7684\u6548\u679c\uff0c\u52a0\u4e0a\u5b8f\u7684\u8bdd\u5f88\u591a\u65f6\u5019\u53ef\u4ee5\u5229\u7528\u6765\u5b9e\u73b0 Metadata \u7684\u6548\u679c\uff0c\u4f8b\u5982\uff1a #define PROPERTY(NAME) \\ Property NAME{this, #NAME}; class Registry { friend class Property; public: int&amp; getValueByName(const std::string &amp;name) { return *values_[name]; } protected: void registerValue(const std::string name, int* &hellip; <a href=\"https:\/\/www.csslayer.info\/wordpress\/linux\/a-small-trick-about-pimpl\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[229,231,230],"class_list":["post-2322","post","type-post","status-publish","format-standard","hentry","category-linux","tag-c","tag-c11","tag-pimpl"],"_links":{"self":[{"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/posts\/2322","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/comments?post=2322"}],"version-history":[{"count":1,"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/posts\/2322\/revisions"}],"predecessor-version":[{"id":2323,"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/posts\/2322\/revisions\/2323"}],"wp:attachment":[{"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/media?parent=2322"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/categories?post=2322"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.csslayer.info\/wordpress\/wp-json\/wp\/v2\/tags?post=2322"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}