九九热这里直有精品,1区二区三区在线播放,玖玖爱在线观看资源,国产aⅴ综合网,午夜福利男女,日本亚洲欧美三级,日韩无码黄色导航,内射少妇13区,中文字幕高清网

您身邊的軟件定制專家--9年開發(fā)經(jīng)驗(yàn)為您護(hù)航

18678812288
0531-88887250

C++設(shè)計(jì)模式——迭代器模式

文章作者:濟(jì)南軟件開發(fā) 時(shí)間:2016年11月08日

  View Code

  再回頭看看,自己寫的代碼都有點(diǎn)不認(rèn)識(shí)了。是的,那個(gè)時(shí)候,就是直接將鏈表的創(chuàng)建和遍歷都放在一類中,就是為了方便,直到那天看了迭代器設(shè)計(jì)模式,讓我有了一次回過頭來重新審視自己寫過的代碼,認(rèn)識(shí)自己的不足的機(jī)會(huì)。

  迭代器模式

  在GOF的《設(shè)計(jì)模式:可復(fù)用面向?qū)ο筌浖幕A(chǔ)》一書中對(duì)迭代器模式是這樣說的:提供一種方法順序訪問一個(gè)聚合對(duì)象中各個(gè)元素,而又不需要暴露該對(duì)象的內(nèi)部表示。

  一個(gè)聚合對(duì)象,就是所謂的對(duì)象容器了;作為一個(gè)容器,都應(yīng)該提供一種方法來讓別人可以訪問它的元素;但是,有的時(shí)候,我是不希望遍歷容器的人知道我的容器是如何實(shí)現(xiàn)的;那該怎么辦?就像我在大學(xué)那樣實(shí)現(xiàn)的鏈表,只提供了從頭到尾的遍歷,如果我需要從尾到頭的遍歷呢?是不是我又要添加對(duì)應(yīng)的方法了呢!??!容器的遍歷方式千變?nèi)f化,我們不知道需求是如何的,如果需求變了,那么我們的代碼就會(huì)發(fā)生很大的改動(dòng),所以,我們需要去改變;對(duì)于上面的代碼,當(dāng)我對(duì)同一個(gè)鏈表對(duì)象進(jìn)行多次遍歷時(shí),是不是就出現(xiàn)了m_pCurrent對(duì)象混亂的局面呢?是的,這一切的一切,都說明,我們必須去將一個(gè)容器的內(nèi)部結(jié)構(gòu)與它的遍歷進(jìn)行解耦,要是出現(xiàn)上面的情況時(shí),我們就無法面對(duì)。就好比STL中的容器,它將容器中對(duì)象的實(shí)現(xiàn)和遍歷很好的解耦了,所以,我們就無法知道它的內(nèi)部是如何組織對(duì)象數(shù)據(jù)的,同時(shí),我們也可以按照我們自己的想法去遍歷容器,而不會(huì)出現(xiàn)任何差錯(cuò)。在我們的項(xiàng)目中使用迭代器模式就能很好的將容器對(duì)象的內(nèi)部表示與對(duì)它的遍歷進(jìn)行解耦。接下來,我們?cè)賮碓敿?xì)的總結(jié)迭代器模式。

  UML類圖

  Iterator:定義迭代器訪問和遍歷元素的接口;

  ConcreteIterator:實(shí)現(xiàn)具體的迭代器;

  Aggregate:定義的容器,創(chuàng)建相應(yīng)迭代器對(duì)象的接口;

  ConcreteAggregate:具體的容器實(shí)現(xiàn)創(chuàng)建相應(yīng)迭代器的接口,該操作返回ConcreteIterator的一個(gè)適當(dāng)?shù)膶?shí)例。

  使用場(chǎng)合

  訪問一個(gè)聚合對(duì)象的內(nèi)容而無需暴露它的內(nèi)部表示;

  支持對(duì)聚合對(duì)象的多種遍歷(從前到后,從后到前);

  為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口,即支持多態(tài)迭代。

  作用

  它支持以不同的方式遍歷一個(gè)聚合,甚至都可以自己定義迭代器的子類以支持新的遍歷;

  迭代器簡化了聚合的接口,有了迭代器的遍歷接口,聚合本身就不再需要類似的遍歷接口了。這樣就簡化了聚合的接口;

  在同一個(gè)聚合上可以有多個(gè)遍歷,每個(gè)迭代器保持它自己的遍歷狀態(tài);因此,我們可以同時(shí)進(jìn)行多個(gè)遍歷。

  代碼實(shí)現(xiàn)

  View Code

  代碼中實(shí)現(xiàn)了一個(gè)單向鏈表,將鏈表與迭代器解耦。對(duì)于多態(tài)迭代,添加抽象類AbstractJTList,聲明如下:

  View Code

  類JTList繼承該抽象類,并實(shí)現(xiàn)GetIterator,如下:

  View Code

  好了,這樣的話,在客戶端就不用去new JTListIterator了,只需要這樣:

  1 Iterator *pIterator = pJTList->GetIterator();

  這就完全好了;但是,這樣又出現(xiàn)另外一個(gè)問題,我在GetIterator中new了一個(gè)JTListIterator,對(duì)于客戶端來說,我并不知道這個(gè)new操作的存在,就會(huì)出現(xiàn)客戶端不會(huì)去釋放這個(gè)new開辟的內(nèi)存,那么如何實(shí)現(xiàn)這個(gè)內(nèi)存的自動(dòng)釋放呢。好了,就結(jié)合迭代器模式,再將之前總結(jié)的RAII機(jī)制再實(shí)際運(yùn)用一次。

  根據(jù)RAII機(jī)制,需要將這個(gè)迭代器進(jìn)行封裝,讓它具有自動(dòng)釋放的功能,就得借助另一個(gè)類,如下:

  復(fù)制代碼

  1 class IteratorPtr

  2 {

  3 public:

  4      IteratorPtr(Iterator *pIterator) : m_pIterator(pIterator){}

  5      ~IteratorPtr() { delete m_pIterator; }

  6

  7      Iterator *operator->(){ return m_pIterator; }

  8      Iterator &operator*() { return *m_pIterator; }

  9

  10 private:

  11      IteratorPtr(const IteratorPtr &);

  12      IteratorPtr &operator=(const IteratorPtr &);

  13      void *operator new(size_t size);

  14      void operator delete(void *);

  15

  16 private:

  17      Iterator *m_pIterator;

  18 };

  復(fù)制代碼

  我們?cè)谑褂玫臅r(shí)候,就像下面這樣:

  1 IteratorPtr pIterator(pJTList->GetIterator());

  這樣就省去了釋放迭代器的麻煩了。這里一共涉及了三個(gè)DEMO工程,提供完整DEMO工程下載。(工程下載)

  總結(jié)

  迭代器模式是一個(gè)很經(jīng)典的模式。但是,就是因?yàn)樗?jīng)典了,如果每次都要程序員去重復(fù)造輪子,就有點(diǎn)說不過去了,所以,現(xiàn)在基本成型的類庫,都非常好的實(shí)現(xiàn)了迭代器模式,在使用這些類庫提供的容器時(shí),并不需要我們親自去實(shí)現(xiàn)對(duì)應(yīng)的迭代器;就好比STL了。但是話又說回來了,如此經(jīng)典的東西,你不去學(xué)習(xí)是不是很可惜??;是吧,在當(dāng)今社會(huì),技多不壓身。好了,永遠(yuǎn)記住,設(shè)計(jì)模式是一種思想,并不是一層不變的,一種思想,你懂的。


想要了解更多詳情歡迎來電咨詢18678812288
登陸網(wǎng)址:m.h6244.cn。
聯(lián)系人:王經(jīng)理。

措美县| 永安市| 公安县| 新津县| 甘孜| 根河市| 古田县| 榆社县| 宝清县| 宁化县| 武山县| 开远市| 临泉县| 九寨沟县| 星座| 项城市| 海南省| 霍城县| 祁东县| 安康市| 河池市| 宁德市| 松桃| 和平区| 乌鲁木齐市| 聊城市| 高唐县| 兴安盟| 黔东| 休宁县| 景东| 上高县| 呈贡县| 曲沃县| 玉环县| 阿尔山市| 克什克腾旗| 新晃| 麻栗坡县| 平和县| 宝鸡市|