<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鲁丝一区二区三区| baoyu777永久免费视频 | 亚洲另类小说图片| 99热在线观看免费| 亚洲白色白色永久观看| 99久久人妻精品免费二区| 亚洲视频网站在线观看| 97视频免费在线| 亚洲综合无码一区二区痴汉| 噼里啪啦电影在线观看免费高清| 国产精品高清视亚洲一区二区 | 91在线视频免费看| 国产亚洲中文日本不卡二区| 成人免费a级毛片无码网站入口| 亚洲GV天堂无码男同在线观看| 免费在线观看中文字幕| a级毛片免费网站| 亚洲日韩图片专区第1页| 无人在线直播免费观看| 老牛精品亚洲成av人片| 亚洲日韩精品无码一区二区三区| 无码A级毛片免费视频内谢| 亚洲宅男精品一区在线观看| 国产禁女女网站免费看| 无码精品人妻一区二区三区免费| 久久精品国产精品亚洲艾草网| 亚洲黄色免费网站| 国产亚洲精品欧洲在线观看| 国产亚洲综合久久系列| 天天影院成人免费观看| 国产成人亚洲午夜电影| 亚洲AV人无码综合在线观看| 18禁成年无码免费网站无遮挡| 又黄又大的激情视频在线观看免费视频社区在线 | 最新69国产成人精品免费视频动漫| 日亚毛片免费乱码不卡一区| 亚洲AV日韩AV永久无码久久| 蜜桃精品免费久久久久影院| 97超高清在线观看免费视频|