日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

Effective C++笔记_条款31将文件间的编译依存关系降至最低

發布時間:2025/4/9 c/c++ 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Effective C++笔记_条款31将文件间的编译依存关系降至最低 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Effective C++筆記_條款31將文件間的編譯依存關系降至最低

? ? ? 這個章節,讀了兩遍還是不是很清楚,有一種沒法和作者溝通的感覺,看來我還是一個C++的初學者呀。好吧,不多說了,回歸主題,今天的筆記。

? ? ? 章節一開始就弄了個例子來說明文件間的編譯依存關系以及串聯的依存關系。代碼如下:

1 #include<string> 2 #include"date.h" 3 #include"address.h" 4 class Person { 5 public: 6 Person(const std::string& name, const Date& birthday, const Address& addr); 7 std::string name() const; 8 std::string birthDate() const; 9 std::string address() const; 10 //... 11 private: 12 /*實現條目*/ 13 std::string theName; 14 Date theBirthDate; 15 Address theAddress; 16 };

1.Person 定義文件和其含入文件之間形成:編譯依存關系,這些頭文件有任何一個被改變,?或這些頭文件所依賴的其他頭文件有任何改變,那么每一個含有Person class的文件就得重新編譯,任何使用Person class的文件也必須編譯:連串編譯依存關系。

2. 為了解決上述問題,可以把Person分割為兩個classes,一個只提供接口(Person),另一個負責實現該接口(PersonImpl)。具體示例代碼如下:

1 // Person 接口 2 #include <string> 3 #include <memory> 4 5 // 前置聲明 6 class PersonImpl; // Handle classes 7 class Date; 8 class Address; 9 10 class Person { 11 public: 12 Person(const std::string& name, const Date& birthday, const Address& addr); 13 std::string name() const; 14 std::string birthDate() const; 15 std::string address() const; 16 //... 17 private: 18 // pimpl idiom(pointer to implementation) 19 std::tr1::shared_ptr<PersonImpl> pImpl; // 指針,指向實現物,shared_ptr 在memory頭文件 20 };

3.編譯依存性最小化的本質:現實中讓頭文件盡可能自我滿足,萬一做不到,則讓它與其他文件內的聲明式(而非定義式)相依。
(1)如果使用object reference或object pointers可以完成任務,就不要使用objects。
(2)如果能夠,盡量以class聲明式替換class定義式。
(3)為聲明式和定義式提供不同的頭文件。

1 // Person 的Handle class,實現Person class中的接口 2 #include "Person.h" // Person的定義式 3 // include PersonImpl的class定義式,用于調用其成員函數, 4 // 注意PersonImpl有著和Person完全相同的成員函數。兩者接口完全相同 5 #include "PersonImpl.h" 6 7 Person::Person(const std::string& name, const Date& birthday, const Address& addr) 8 :pImpl(new PersonImpl(name, birthday, addr)) 9 {} 10 11 std::string Person::name() const 12 { 13 return pImpl->name(); //讓Person變成一個Handle class 并不會改變它做的事,智慧改變它做事的方法 14 }

4.方案二:Interface class ,令Person成為一種特殊的abstract base class
?  Interface class:
  (1) ? 目的:詳細一一描述derived classes的接口
  ?(2)通常不帶成員變量,也沒有構造函數,只有一個virtual析構函數以及一組pure virtual 函數,用來敘述整個接口。

1 class Person { 2 public: 3 virtual ~Person(); 4 virtual std::string name() const = 0; 5 virtual std::string birthDate() const = 0; 6 virtual std::string address() const = 0; 7 //... 8 };

? ? ? Interface class 的客戶,通常調用一個特殊函數(factory函數或virtual構造函數):扮演“真正將被具現化”的那個derived classes的構造函數角色。它們返回指針(智能指針),指向動態分配所得對象,而該對象支持Interface class的接口。它們通常被聲明為static。

1 class Person { 2 //... 3 static std::tr1::shared_ptr<Person> 4 create(const std::string& name, const Date& birthday, const Address& addr); 5 };

? ??支持Interface class 接口的那個具體類必須被定義出來,而且真正的構造函數必須被調用。一切都在virtual構造函數實現碼所在的文件中。

1 class RealPerson: public Person { 2 public: 3 RealPerson(const std::string& name, const Date& birthday, const Address& addr) 4 :theName(name), theBirthDate(birthday), theAddress(addr) 5 {} 6 virtual ~RealPerson() {} 7 std::string name() const; 8 std::string birthDate() const; 9 std::string address() const; 10 //... 11 private: 12 /*實現條目*/ 13 std::string theName; 14 Date theBirthDate; 15 Address theAddress; 16 17 }; 18 19 std::tr1::shared_ptr<Person> Person::create(const std::string& name, 20 const Date& birthday, 21 const Address& addr) 22 { 23 return std::tr1::shared_ptr<Person>(new RealPerson(name, birthday, addr)); 24 }

RealPerson示范實現了Interface class的兩個常見機制:
  (1)從Interface class繼承接口規格,然后實現出接口所覆蓋的函數.
  (2)實現法涉及多重繼承。

5.Handle classes 和Interface classes解除了接口和實現之間的耦合關系,從而降低文件間的編譯依存性。但是存在的缺點是:它使你在運行期喪失若干速度,又讓你為每個對象超額付出若干內存。

具體如下:
? ? ?在Handle classes身上,成員函數必須通過implementation pointer 取得對象數據。那會為每一次
訪問增加一層間接性。而每一個對象消耗的內存數量必須增加implmentation pointer的大小。最后,
implementation pointer必須初始化。指向一個動態分配得來的implementation object,所以你
將蒙受因動態內存分配(及后的釋放動作)而來的額外開銷,以及遭遇bad_alloc異常(內存不足)
的可能性。

? ? ?Interface classes,由于每個函數都是virtual,所以你必須為每次函數調用付出一個間接跳躍
成本。此外Interface class派生的對象必須內含一個vptr,這個指針可能會增加放對象所需的內存
數量---實際取決于這個對象除了interface class之外是否還有其他virtual函數來源。

------------------------------------------------------------------------------------------------------------------------------------------

總結:

?支持“編譯依存性最小化”的一般構想:相依于聲明式,不要相依與定義式。基于次構想的兩個手段是Handle classes和Interface classes。

?程序庫頭文件應該以“完全且僅有聲明式”的形式存在。這種做法不論是否涉及templates都適用。


?

聲明:全文文字都是來源《Effective C++》 3th。這里所寫都是自己的讀書的時候梳理做的筆記罷了。希望對他人有用,那是我的榮幸。

posted on 2015-03-23 20:28?CloudFeng 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/cloudfeng/p/4360909.html

總結

以上是生活随笔為你收集整理的Effective C++笔记_条款31将文件间的编译依存关系降至最低的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲国产精品18久久久久久 | 一区二区片 | 黄色片视频免费 | 欧美精品乱码视频一二专区 | 玖玖爱在线精品视频 | 天天爽天天摸 | 夫妻黄色片| 后进极品美女白嫩翘臀 | 欧美影视一区二区 | 欧美黄色大全 | 国产jizz18女人高潮 | 国产交换配乱淫视频免费 | 国产在线一区二 | 青青草免费在线观看视频 | 国产性猛交xxxⅹ交酡全过程 | 久久一区二区三区视频 | 性高跟鞋xxxxhd国产电影 | 日韩精品人妻一区二区中文字幕 | 四川操bbb| 波多野结衣在线免费观看视频 | av天天射| 人人叉人人 | 亚洲AV无码久久精品浪潮 | 欧美猛操 | 国产熟妇另类久久久久 | 污污网站在线 | 琪琪射 | 精品亚洲永久免费 | 亚洲一区二区不卡视频 | 亚洲欧美另类在线视频 | 成年人黄色一级片 | 成人看的毛片 | 黄频视频在线观看 | 97超级碰碰碰 | 在线免费观看你懂的 | 欧美日韩国产中文 | 欧美36p| 曰批免费视频播放免费 | 欧美午夜小视频 | 少妇xxx| 中文字幕99 | 欧美三p| 九九九在线观看 | 久久久久久久蜜桃 | 欧美交换| 欧美丰满一区二区免费视频 | 性淫影院 | 免费啊v在线观看 | 在线视频欧美一区 | 久久77777| 特级毛片在线 | 女性高潮视频 | 天天摸天天舔 | 亚洲精品乱码久久久久久蜜桃图片 | av中文字幕网 | 中文字幕av一区二区三区人妻少妇 | 一区二区视| 久久国产影视 | aa片在线观看视频在线播放 | 欧美久久久 | 亚洲国产精品美女 | 亚洲v欧美v另类v综合v日韩v | 国产色视频一区二区三区qq号 | 91激情 | 国产精品专区在线观看 | 男人看的网站 | a一级黄色 | 在线免费观看的av | 性――交――性――乱睡觉 | 特级西西www444人体聚色 | 日本小视频网站 | h网站在线播放 | 最新中文字幕在线观看 | 亚洲天堂中文字幕在线 | 被灌满精子的波多野结衣 | 日本三级视频网站 | 国产精品自拍合集 | 五月天婷婷丁香花 | 国产伦人伦偷精品视频 | 亚洲天堂黄 | 中文区中文字幕免费看 | 神马午夜在线观看 | 狠狠艹狠狠干 | 寡妇一级片 | 在线h网| 久久色在线视频 | 91毛片在线观看 | 色呦呦官网 | av污| 国产91一区二区三区 | 欧美日韩欧美 | 黄色一集片 | 国模人体一区二区 | 西西人体44www大胆无码 | 欧美日韩观看 | 亚洲人成在线观看 | 一级女人毛片 | 亚洲精选在线观看 | 久久精品国产99久久久 |