<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    LALA  
    日歷
    <2010年8月>
    25262728293031
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    導航

    留言簿(1)

    隨筆分類(31)

    文章分類(4)

    收藏夾(21)

    搜索

    •  

    積分與排名

    • 積分 - 30055
    • 排名 - 1390

    最新隨筆

    最新評論

    閱讀排行榜

     
    在讀《Effective C++》和項目源代碼時,看到pImpl Idiom。它可以用來降低文件間的編譯依賴關系,通過把一個Class分成兩個Class,一個只提供接口,另一個負責實現該接口,實現接口與實現的分離。這個分離的關鍵在于“以聲明的依賴性”替換“定義的依賴性”,而編譯依賴性最小化的本質是:讓頭文件盡可能的自我滿足,萬一做不到,則讓它與其他文件內的聲明式(而非定義式)相依。

    引用這里的一些描述:
    The Pimpl idiom, also known as the compilation firewall or Cheshire Cat technique, is a "private implementation" technique useful only in CeePlusPlus and statically compiled languages like it...

    Benefits:
    1. Changing private member variables of a class does not require recompiling classes that depend on it, thus make times are faster, and the FragileBinaryInterfaceProblem is reduced.
    2. The header file does not need to #include classes that are used 'by value' in private member variables, thus compile times are faster.
    3. This is sorta like the way SmallTalk automatically handles classes... more pure encapsulation.
    Drawbacks:
    1. More work for the implementor.
    2. Doesn't work for 'protected' members where access by subclasses is required.
    3. Somewhat harder to read code, since some information is no longer in the header file.
    4. Run-time performance is slightly compromised due to the pointer indirection, especially if function calls are virtual (branch prediction for indirect branches is generally poor).
    How to do it:
    1. Put all the private member variables into a struct.
    2. Put the struct definition in the .cpp file.
    3. In the header file, put only the ForwardDeclaration of the struct.
    4. In the class definition, declare a (smart) pointer to the struct as the only private member variable.
    5. The constructors for the class need to create the struct.
    6. The destructor of the class needs to destroy the struct (possibly implicitly due to use of a smart pointer).
    7. The assignment operator and CopyConstructor need to copy the struct appropriately or else be disabled.
    Code:
    1???struct?AImp;
    2???class?A?{
    3???public:
    4?????//?Same?public?interface?as?A,?but?all?delegated?to?concrete?implementation.
    5???private:
    6?????AImp?*?pimpl;
    7???};
    8?


    If you use a SmartPointer and you only have one implementation, there is no need to make any of the member functions virtual, except possibly the destructor. The run-time cost of non-virtual member function calls is much lower, and a compiler that does whole-program optimization can inline them even though they're in a separate translation unit. Here's an example:
    ?1??//?foo.h
    ?2?
    ?3???class?foo_impl;
    ?4?
    ?5???class?foo?{
    ?6?????//?Boilerplate
    ?7?????friend?class?foo_impl;
    ?8?????foo()?{}?//?so?only?foo_impl?can?derive?from?foo
    ?9?????const?foo_impl?*?impl()?const;
    10?????foo_impl?*?impl();
    11???public:
    12?????virtual?~foo()?{}
    13?????//?Factories
    14?????static?std::auto_ptr<foo>?create(int?value);
    15?????//?Interface
    16?????int?value()?const;
    17???};
    18?
    19???//?foo.cpp
    20?
    21???class?foo_impl?:?public?foo?{
    22?????friend?class?foo;
    23?????//?Constructors?mirroring?the?factory?functions?in?foo
    24?????explicit?foo_impl(int?value)?:?value_(value)?{}
    25?????//?Member?data
    26?????int?value_;
    27???};
    28?
    29???inline?const?foo_impl?*?foo::impl()?const?{
    30?????return?static_cast<const?foo_impl?*>(this);
    31???}
    32???inline?foo_impl?*?foo::impl()?{
    33?????return?static_cast<foo_impl?*>(this);
    34???}
    35?
    36???std::auto_ptr<foo>?foo::create(int?value)?{
    37?????return?std::auto_ptr<foo>(new?foo_impl(value));
    38???}
    39?
    40???int?foo::value()?const?{?return?impl()->value_;?}
    41?
    42?

    Here, the destructor needs to be declared virtual foo so that std::auto_ptr<foo> calls foo_impl's destructor. If you use boost::shared_ptr<foo> instead, even that doesn't need to be virtual, because shared_ptr remembers how to call the correct destructor. (This doesn't improve performance or memory use, because shared_ptr is larger and slower than auto_ptr, but if you need to use shared_ptr anyway you may as well eliminate the virtual destructor.) -- BenHutchings


    參考閱讀:

    Effective C++
    http://c2.com/cgi/wiki?PimplIdiom
    http://en.wikipedia.org/wiki/Opaque_pointer
    posted on 2010-08-07 22:58 Dest 閱讀(921) 評論(0)  編輯  收藏 所屬分類: C++
     
    Copyright © Dest Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 免费鲁丝片一级在线观看| 国产成人无码免费看视频软件| 免费无遮挡无码永久在线观看视频| 亚洲国产成人无码av在线播放| 蜜桃视频在线观看免费视频网站WWW| 亚洲中文字幕无码久久2017| 四虎影在线永久免费四虎地址8848aa | 国产精品免费久久久久电影网| 91精品啪在线观看国产线免费| 久久久久久久尹人综合网亚洲| 两个人看www免费视频| 亚洲国产日韩在线视频| 国产一级片免费看| 亚洲欧洲精品视频在线观看| 18成禁人视频免费网站| 亚洲成人免费电影| 国产成人免费ā片在线观看 | 亚洲人成国产精品无码| 久久99精品免费一区二区| 久久国产亚洲观看| ww在线观视频免费观看| 中文字幕在线日亚洲9| 免费成人午夜视频| 免费观看一区二区三区| 亚洲成人福利网站| 免费观看国产小粉嫩喷水| 国产人成网在线播放VA免费| 亚洲AV无码久久精品蜜桃| 性xxxxx免费视频播放| 亚洲成a∨人片在无码2023| 久久久久亚洲av毛片大| 亚洲精品免费视频| 亚洲日韩看片无码电影| 久久久久亚洲AV综合波多野结衣| 日本免费大黄在线观看| 亚洲精品av无码喷奶水糖心| 亚洲亚洲人成综合网络| 日韩精品成人无码专区免费| 九九免费精品视频在这里| 亚洲成a人片毛片在线| 亚洲国产专区一区|