<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)

    搜索

    •  

    積分與排名

    • 積分 - 29818
    • 排名 - 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 閱讀(914) 評論(0)  編輯  收藏 所屬分類: C++
     
    Copyright © Dest Powered by: 博客園 模板提供:滬江博客
    主站蜘蛛池模板: 久久精品亚洲福利| 免费乱理伦在线播放| 久久精品国产亚洲AV高清热| 一级视频免费观看| 国产亚洲?V无码?V男人的天堂 | 亚洲天堂2016| 亚洲国产精品免费观看| 亚洲人成人网毛片在线播放| 91香蕉成人免费网站| 亚洲色偷偷色噜噜狠狠99网| 免费观看毛片视频| 日本中文字幕免费看| 亚洲精品中文字幕乱码三区| 无码国产精品一区二区免费vr| 亚洲一卡2卡三卡4卡有限公司| 91视频免费网址| 国产成人精品日本亚洲直接| 欧洲美熟女乱又伦免费视频| 阿v免费在线观看| 亚洲精品乱码久久久久久| 香港a毛片免费观看| 亚洲人成电影在线观看网| 永久免费bbbbbb视频| 国产精品免费久久久久久久久 | 亚洲JLZZJLZZ少妇| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 国产乱码免费卡1卡二卡3卡| 亚洲AV日韩综合一区| 久久久久亚洲AV综合波多野结衣 | 亚洲国产精品VA在线看黑人| 国产h视频在线观看网站免费| 亚洲av无码日韩av无码网站冲| 亚洲国产一区二区三区| 全部免费毛片在线播放| 亚洲爆乳无码精品AAA片蜜桃| 亚洲人妻av伦理| 国产免费不卡v片在线观看| 思思久久99热免费精品6| 亚洲黄色在线网站| 亚洲成?Ⅴ人在线观看无码| 国产精品成人免费一区二区|