读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第二部分)...
下面再來(lái)看書(shū),去理解書(shū)上說(shuō)的Handler classes就簡(jiǎn)單多了,我們大概過(guò)一下。
假設(shè)我們要寫(xiě)一個(gè)Person類,如下:
1 class Person 2 { 3 private: 4 string name; 5 MyDate birthday; 6 MyAddress address; 7 8 public: 9 // fallows functions 10 // ... 11 };這個(gè)Person類里面包含有人的名字,人的生日以及地址,還有一些沒(méi)有列出來(lái)的方法。注意到這里用到了string(它不是一個(gè)class,只是一個(gè)typedef,大多數(shù)情況下,我們認(rèn)為它不會(huì)有任何改變),以及自定義的類MyDate與MyAddress,一種常見(jiàn)的做法是采用include頭文件,像這樣:
1 #include <string> 2 #include "MyDate.h" 3 #include "MyAddress.h"在MyDate.h里面寫(xiě)好日期類相關(guān)的成員變量與方法,而在MyAddress.h里面寫(xiě)好地址類相關(guān)的成員變量與方法。但如果此后要往MyDate類或者M(jìn)yAddresss類添加成員變量,那么不僅僅所有用到MyDate或者M(jìn)yAddress對(duì)象的文件需要重新編譯,而且所有用到Person對(duì)象的文件也需要重編譯,一個(gè)小改動(dòng)竟然會(huì)牽涉到這么多的地方!
?
可以把問(wèn)題歸結(jié)為“C++并沒(méi)有把將接口從實(shí)現(xiàn)中分離這件事做好”,因?yàn)榘^文件的做法很直觀很方便,用的人也很普遍,而C++并沒(méi)有對(duì)這種做法加以限制。
如果要把編譯的依賴性降低,就要換一種思路來(lái)處理,不能出現(xiàn)定義式,只能出現(xiàn)聲明式,代價(jià)是增加代碼的復(fù)雜度以及性能上的一些損失。
?
書(shū)上提到了兩種方法,第一種是采用Handler Classes(用指針指向真正實(shí)現(xiàn)的方法),第二種是Interface Classes(抽象基類)。
?
對(duì)于第一種Handler Class,一句話,就是.h里面不包含類的自定義頭文件,用“class 類名”的聲明方式進(jìn)行代替(也要把相應(yīng)的成員變量替換成指針或引用的形式),在.cpp文件里面包含類的自定義頭文件去實(shí)現(xiàn)具體的方法。改造之后的程序看起來(lái)是這樣子的:
1 // Person.h 2 #include <string> 3 using namespace std; 4 5 class PersonImp; 6 7 class Person 8 { 9 private: 10 //string Name; 11 //MyDate Birthday; 12 //MyAddress Address; 13 PersonImp* MemberImp; 14 15 public: 16 string GetName() const; 17 string GetBirthday() const; 18 string GetAddress() const; 19 // follows functions 20 // ... 21 }; 1 // Person.cpp 2 #include "PersonImp.h" 3 #include "Person.h" 4 5 string Person::GetName() const 6 { 7 return MemberImp->GetName(); 8 } 9 string Person::GetBirthday() const 10 { 11 return MemberImp->GetName(); 12 } 13 string Person::GetAddress() const 14 { 15 return MemberImp->GetAddress(); 16 } 1 // PersonImp.h 2 #ifndef PersonImp_H 3 #define PersonImp_H 4 5 #include <string> 6 #include "MyAddress.h" 7 #include "MyDate.h" 8 using namespace std; 9 10 class PersonImp 11 { 12 private: 13 string Name; 14 MyAddress Address; 15 MyDate Birthday; 16 17 public: 18 string GetName() const 19 { 20 return Name; 21 } 22 23 string GetAddress() const 24 { 25 return Address.ToString(); 26 } 27 28 string GetBirthday() const 29 { 30 return Birthday.ToString(); 31 } 32 }; 33 34 #endif /* PersonImp_H */ 1 // MyDate.h 2 #ifndef MY_DATE_H 3 #define MY_DATE_H 4 5 #include <string> 6 using namespace std; 7 8 class MyDate 9 { 10 private: 11 int Year; 12 int Month; 13 int DayOfMonth; 14 15 public: 16 string ToString() const; 17 } 18 #endif /* MY_DATE_H */ 1 // MyAddress.h 2 #ifndef MY_ADDRESS_H 3 #define MY_ADDRESS_H 4 5 #include <string> 6 using namespace std; 7 8 class MyAddress 9 { 10 private: 11 string Country; 12 string Province; 13 string City; 14 string Street; 15 16 public: 17 string ToString() const; 18 }; 19 20 #endif /* MY_ADDRESS_H */這里有一點(diǎn)要說(shuō)一下,在Person.h里面并沒(méi)有使用MyDate*和MyAddress*,而是用了PersonImp*,由PersonImp里面包含MyDate與MyAddress,這樣做的好處就是方便統(tǒng)一化管理,它要求PersonImp里面的方法與Person的方法是一致的。以后Person添加成員變量,可以直接在PersonImp中進(jìn)行添加了,從而起到了隔離和隱藏的作用,因?yàn)榭蛻舳舜a大量使用的將是Person,而不必關(guān)心PersonImp,用于幕后實(shí)現(xiàn)的PersonImp只面向于軟件開(kāi)發(fā)者而不是使用者。
書(shū)上是用shared_ptr來(lái)管理PersonImp的,使資源管理上更加科學(xué)與合理。
另外,書(shū)上也提倡把class x; class xx; class xxx;的聲明放至一個(gè)名為”xxxfwd.h”的頭文件里,比如”datefwd.h”,這個(gè)頭文件里面只有聲明式,而沒(méi)有具體的類細(xì)節(jié)。也就是說(shuō),對(duì)于某個(gè)類,比如MyDate,應(yīng)該分出三個(gè)文件,一個(gè)是datefwd.h,里面是一些用到的外來(lái)的class聲明式;一個(gè)是MyDate.h里面是MyDate類的結(jié)構(gòu)聲明;一個(gè)是MyDate.cpp,它與MyDate.h配對(duì),給出具體的實(shí)現(xiàn)細(xì)節(jié)。
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/jerry19880126/p/3551839.html
總結(jié)
以上是生活随笔為你收集整理的读书笔记_Effective_C++_条款三十一:将文件间的编译依存关系降至最低(第二部分)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 支付系统灰度发布原理图
- 下一篇: 如何修改ant-input的高度_如何利