青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

第二桶 基于對象的編程 第三碗 老C首演迭代模式 小P決定深練內功

     “感覺這一家有做大的趨勢……”老C一邊喝茶消食一邊對小P發表自己的看法。
     “的確,他家已經把旁邊的店生意快搶光了,估計過一些時間就會把隔壁的店買下來了。”小P亦有同感,“怪不得最近食堂的刀削面師傅辭工,可能創業去了……”
     “?是么?呵呵,也許吧。”老C笑道,“不過看在你請客的面子上,我決定和你多聊幾句……”
     “哦,是的是的。你要告訴我如何更好的實現線性表。”小P接道。
     “嘻嘻,是的是的。不過這次我要先寫一段代碼……”老C說道。
     “……是啊……”小P于是很自覺的將白板擦干凈,并拉到兩人面前。
     “我們現在的題目是,寫一個函數,作用是在一個線性表中查找某一個特定元素。”老C說道,“我們先從數組開始,這樣比較簡單。”


int* find (int* first, int* last, const int val);

int* find(int* first, int* last, const int val)
{
    for (; first != last; ++first)
    {
        if (val == *first)
        {
            break;
        }
    }

    return first;
}

     “在這里我們用[first, last)表示需要查找的區間,如果找到就返回元素的指針,否則返回last。”老C解釋,“為了更清楚的表明此函數所在的應用環
境,我們再來一段使用它的代碼。”

#include <iostream>

int* find (int* first, int* last, const int val);

const int MAX_SIZE = 5;

int main()
{
    int a[MAX_SIZE] = {0, 1, 2, 3, 4};

    const int* iter = find(&a[0], &a[MAX_SIZE], 3);

    if (iter != &a[MAX_SIZE])
    {
        std::cout << "The element is at NO. " << (iter - &a[0]) + 1 << " position." << std::endl;
    }
    else
    {
        std::cout << "Not be found!" << std::endl;
    }
}


int* find(int* first, int* last, const int val)
{
    for (; first != last; ++first)
    {
        if (val == *first)
        {
            break;
        }
    }

    return first;
}

     “看,find()函數就是這樣被使用的。”老C說道,“同時我要提醒一下你,數組類型與指針類型是不同的類型,因為數組類型還帶有數組長度的信息。比如 int a[2] 與 int* a,這是兩種類型,其中int a[]可以被內部轉型為int* ,但是反之則不行??上У氖菙到M類型無法作為函數參數,在使用函數對數組進行操作的時候不得不將其轉型為指針……這個就是C中的數組降維問題……總之你要 明白,數組與指針是不同的類型,但數組可以被轉型為指針——代價是丟失長度信息——反之則不行。”
     “好,我了解了。”小P回答,心想好像在哪本書上說過貌似數組和指針沒有什么區別的。為了確認這個事情,他決定再google一下。
     “喏,如果我們使用了[first, last)的表達形式,很多對線性表的操作就可以統一起來,這樣我們將指向線性表元素的指針提取出來,就使得用戶使用這些線性表就好像在使用一個數組似 的。這樣會大大減輕用戶記憶的難度,同時也使得編程人員避免了很多下意識的錯誤——比如過一錯誤。”老C說道,“而這個被提煉出來的指針,我們就叫它 iterator。”
     “是么?”小P道,“原來iterator就是這樣來的啊。”
     “剛才的例子是trivial的,我們再深入一點點。”老C說道,“如果我們希望find()函數可以被運用到所有類型的線性表,那么可以怎么做呢?”看 到小P有些槑,老C自問自答,“其實方法有很多,我們可以將find()看成對象——一切皆為對象——如果使用面向對象的方法,然后提煉出一個find 類,讓findVector和findList成為它的子類,find類中的操作寫為虛函數,然后讓findVector子類和findList子類去修 改這些虛函數以滿足自己的實際需要,這可以被稱為strategy模式的一個簡單應用。但是這個方法我們先避開不談,在這里我們采用另外一個方法。”他找 到茶杯喝了一口,“我們將這個iterator提煉為一個類,同時保持find()函數的實現不變,然后在這個iterator上動腦筋。”
     “那么應當怎么做呢?”小P問道。
     “嗯,如果find()函數的代碼不變,那么我們可以這么做。”老C說著打開了電腦,新建立了一個工程開始敲鍵盤,一邊敲一邊給小P解釋著。

find.h:

#if !defined(FIND_H_)
#define FIND_H_

#include "iterator.h"

Iterator& find(Iterator& first, Iterator& last, const ValueType& val)
{
    for (; first != last; ++first)
    {
        if (val == *first)
        {
            break;
        }
    }

    return first;
}

#endif // FIND_H_

     “看,我們希望的finde()函數可以是這樣的一種接口和實現。”老C解釋,“而且希望它可以這樣被使用。”

main.cpp:

#include "implement.h"
#include "find.h"

#include <iostream>

const int MAX_SIZE = 5;

int main()
{
    IntValueType a[MAX_SIZE] = {0, 1, 2, 3, 4};

    IntVector intVec(&a[0], &a[MAX_SIZE]);
    IntList intList(&a[0], &a[MAX_SIZE]);

    //IntVectorIter first = intVec.begin();
    //IntVectorIter last = intVec.end();

    IntListIter first = intList.begin();
    IntListIter last = intList.end();

    Iterator& it = find(first, last, IntValueType(4));

    if (it != last)
    {
        std::cout << "Find " << (*it) << std::endl;
    }
    else
    {
        std::cout << "Cannot find " << std::endl;
    }    

    return 0;
}

     “在這里我們假設find()函數即可以用在vector上,也可以用在linked list上,橋梁就是Iterator類。”老C解釋道,“這下我們就可以根據find()函數的實現看看我們需要什么樣子的Iterator類的接口了。”

class Iterator
{
public:
    virtual Iterator& operator++() = 0;

    virtual ValueType& operator*() = 0;

    virtual bool operator==(Iterator& rhs) = 0;

    virtual bool operator!=(Iterator& rhs) = 0;

protected:
    ~Iterator() {}
};

     “根據find()函數的實現,我們知道Iteratro類必須擁有上面列出的接口。在這里我把Iterator類設計為抽象類,因為它只是提供一個接口規范而已。”老C解釋。
     “那么為什么它的析構函數是protected的呢?”小P問。
     “哦,這是一個習慣用法。一般的抽象類的析構函數要么是public virtual的,要么是protected 非virtual的。我在這里將它設計為protected 非virtual是因為我不想讓Iterator動態生成,就是說不希望Iterator的繼承類的對象是在堆上創建的。”看到小P還是有些莫名其妙,老 C接著說,“關于這個小技巧,我會在后面一段時間……一個月后吧……跟一些其他的小技巧一起總結一下,在這里你就先將就著看吧。”
     “也好……”小P槑。
     “接下來的代碼……很傻很天真……”老C解釋道,“因為在這里只是說明問題而已,你可不要學習這種設計啊。”

class ValueType
{
    friend std::ostream& operator<<(std::ostream& os, const ValueType& value);
public:
    virtual ~ValueType() {}

    virtual bool operator==(const ValueType& rhs) const = 0;

    virtual void print(std::ostream& os) const = 0;
};

std:: ostream& operator<<(std::ostream& os, const ValueType& valueType)
{
    valueType.print(os);

    return os;
}

     “因為我們沒有辦法在系統定義類型——比如int——與用戶定義類型——比如Student——間保持一致,而我們又希望對于int數組和Student 數組都可以使用find()函數……不得以,我設計了一個叫做ValueType的傻傻基類,并將int用IntValueType類包裹了一下,使得類 似int這種系統定義類型也可以加入到我們的組織當中。”老C解釋,“為了便于屏幕輸出,我還重載了ostream的輸出函數。”他撓撓頭,“最后我又畫 蛇添足的寫了一個Container的基類,用于存放我們的數據結構。其實它什么也沒有做,只是為了統一下類型而已。”

class Container
{
public:
    virtual ~Container() {}
};

     “最后我們把這些接口放入一個文件當中。”老C新建了一個頭文件,將類的定義放入其中。

iterator.h:

#if !defined(ITERATOR_H_)
#define ITERATOR_H_

#include <iostream>


class Iterator;
class Container;
class ValueType;

//////////////////////////////////////////////////////////////////////////
// Base classes.
//
class Iterator
{
public:
    virtual Iterator& operator++() = 0;

    virtual ValueType& operator*() = 0;

    virtual bool operator==(Iterator& rhs) = 0;

    virtual bool operator!=(Iterator& rhs) = 0;

protected:
    ~Iterator() {}
};

class Container
{
public:
    virtual ~Container() {}
};

class ValueType
{
    friend std::ostream& operator<<(std::ostream& os, const ValueType& value);
public:
    virtual ~ValueType() {}

    virtual bool operator==(const ValueType& rhs) const = 0;

    virtual void print(std::ostream& os) const = 0;
};

std:: ostream& operator<<(std::ostream& os, const ValueType& valueType)
{
    valueType.print(os);

    return os;
}


#endif // ITERATOR_H_

     “下來又是一些天真的實現代碼,”老C不好意思的撓頭,“就先作為說明示例代碼吧,等我們掌握了更多的知識后再來修改這些代碼吧。”

implement.h:

#if !defined(IMPL_H_)
#define IMPL_H_

#include "iterator.h"

#include <cassert>
#include <typeinfo>

//////////////////////////////////////////////////////////////////////////
// Derived classes.
//
// IntVector.
//
class IntValueType : public ValueType
{    
public:
    IntValueType(int content = 0) : content_(content) {}

    virtual bool operator==(const ValueType& rhs) const
    {
        try
        {
            const IntValueType& intValue = dynamic_cast<const IntValueType&>(rhs);    
            return content_ == intValue.content_;
        }
        catch (std::bad_cast e)
        {
            std::cout << "Bad cast, this object is not of type IntValue! " << std::endl;
            return false;
        }        
    }

    virtual void print(std::ostream& os) const
    {
        os << content_;
    }

private:
    int content_;
};


class IntVectorIter : public Iterator
{
public:
    IntVectorIter(IntValueType* ptr = 0) : ptr_(ptr) {}

    virtual Iterator& operator++()
    {
        ++ptr_;

        return *this;
    }

    virtual ValueType& operator*()
    {
        return *ptr_;
    }

    virtual bool operator==(Iterator& rhs)
    {
        try
        {
            IntVectorIter& intIter = dynamic_cast<IntVectorIter&>(rhs);
            return ptr_ == intIter.ptr_;
        }
        catch (std::bad_cast e)
        {
            std::cout << "Bad cast, this object is not of type IntVectorIter! " << std::endl;
            return false;
        }
    }

    virtual bool operator!=(Iterator& rhs)
    {
        return !(operator==(rhs));
    }

private:
    IntValueType* ptr_;

};

class IntVector : public Container
{
public:
    IntVector(IntValueType* first, IntValueType* last)
        : size_(0), array_(0)
    {
        size_ = last - first;
        assert(size_ > 0);

        array_ = new IntValueType[size_];

        for (size_t i = 0; i < size_; ++i)
        {
            *(array_ + i) = *(first + i);
        }
    }

    ~IntVector()
    {
        if (array_)
        {
            delete[] array_;
            array_ = 0;
        }
        size_ = 0;
    }

    virtual IntValueType* begin()
    {
        return &array_[0];
    }

    virtual IntValueType* end()
    {
        return &array_[size_];
    }

private:
    size_t    size_;
    IntValueType*    array_;
};

//
// IntList
//

struct IntNode
{
    IntNode* prev_;
    IntNode* next_;

    IntValueType content_;
};

class IntListIter : public Iterator
{
public:
    IntListIter(IntNode* intNode = 0) : nodePtr_(intNode) {}

    virtual Iterator& operator++()
    {
        nodePtr_ = nodePtr_->next_;

        return *this;
    }

    virtual ValueType& operator*()
    {
        return nodePtr_->content_;
    }

    virtual bool operator==(Iterator& rhs)
    {
        try
        {
            IntListIter& it = dynamic_cast<IntListIter&>(rhs);
            return nodePtr_ == it.nodePtr_;
        }
        catch (std::bad_cast e)
        {
            std::cout << "Bad cast, this object is not of type IntListIter! " << std::endl;
            return false;
        }
    }

    virtual bool operator!=(Iterator& rhs)
    {
        return !(operator==(rhs));
    }

private:
    IntNode* nodePtr_;
};

class IntList : public Container
{
public:
    IntList(IntValueType* first, IntValueType* last)
        : size_(0), list_(0)
    {
        size_ = last - first;
        assert(size_ > 0);

        list_ = new IntNode;        
        list_->prev_ = list_;
        list_->next_ = list_;

        for (size_t i = 0; i < size_; ++i)
        {
            IntNode* newNode = new IntNode;
            newNode->content_ = *(first + i);
            newNode->next_ = list_;
            newNode->prev_ = list_->prev_;
            newNode->prev_->next_ = newNode;
            newNode->next_->prev_ = newNode;
        }
    }

    ~IntList()
    {
        while (list_->next_ != list_)
        {
            IntNode* it = list_->next_;
            it->prev_->next_ = it->next_;
            it->next_->prev_ = it->prev_;

            it->prev_ = 0;
            it->next_ = 0;
            it->content_ = 0;
            delete it;
            it = 0;
        }

        list_->prev_ = 0;
        list_->next_ = 0;
        delete list_;
        list_ = 0;
        size_ = 0;
    }

    virtual IntNode* begin()
    {
        return list_->next_;
    }

    virtual IntNode* end()
    {
        return list_;
    }

private:
    size_t     size_;
    IntNode* list_;
};



#endif // IMPL_H_

     “因為不想多動腦筋,所以代碼中充滿了轉型,這些都是不良的設計。你大概明白一下iterator模式的思想就可以了,以后我們還會優化這些代碼的。”老C說道,“不用太關注代碼的細節,只要知道我們通過運算符重載保證了用戶代碼的簡單明了就達到目的了。”
     “唔,我看看先……”小P回答。他問了幾個代碼中的問題,想了想,說,“看來iterator模式就是將對container中元素的操作與container本身分開,這樣就可以達到復用某些算法的目的?”
     “呵呵,差不多就是這樣啦。”老C回答,“要看懂這些古怪的代碼,還有一些細節需要了解,但是我們不要過于糾纏到細節當中,先從整體上把握一下就可以了。 這些細節問題,當然需要重視,但是不是現在。等我們接觸的代碼再多一些,我們再回頭看看這些細節問題吧。”他揉揉手指,“看,這下find()函數即可以 在vector上使用,也可以在list上使用了吧;而且對于container數據的操作也方便了一些。代價是我們在幕后雜七雜八的搞了一些小動作。” 老C伸了一個懶腰,“等我們掌握了足夠的細節,再回來修改這些代碼吧,先用面向對象的方法,再用模板的方法——不過現在談論這些兒還太早,有害無益,我們 還是先不要太激進的好。”
     “哦?好吧,”小P覺得自己越來越好奇了,“還有面向對象和模板的方法???”
     “是啊是啊,這些我們以后慢慢說……”老C心想一次都搞光了,以后晚飯就沒有人請客了。
     “呵呵,好啊好啊。不過這些代碼我還是要再看看,你給我傳一下吧……”小P道。
     “唉,現在不要糾纏在這些代碼上啦,我們還是要平衡一下……”老C回答,“不過我還是把這些代碼放到服務器上,你用ftp下載吧。”
     “好啊,”小P道,“你說不用糾纏在這些代碼的細節上,那么接下來我們要討論一些什么內容呢?”
     “……”老C深沉了一會,“接下來我們要討論——數學。”
     “數學?”小P奇道。
     “唔,”老C點頭,“我們編碼就像練功,語言啊,代碼結構啊,風格啊什么的就是外功;而解決問題的方法就是內功——內功需要一定的專業知識和數學功底。無 論內外功都是要修煉的……否則哪怕你程序的結構再好,風格再優美,但是你無法解決稍微復雜一些的實際問題——那么一切也是白搭。”
     “是啊,也對。”小P贊同。“那么需要討論些什么內容呢?”
     “呵呵,也不會很復雜,只是一些基本的分析問題,解決問題的基本思路而已。”老C說道,“你的數學還是不錯的,等到融會貫通了,對你來說小菜而已。”老C 想想,“其實不僅僅是數學,我們還可以順便討論一些信號、電路和自控方面的問題。因為編程一定要在項目中進行,在項目中學習得是最快的。等到掌握的知識細 節足夠豐富的時候,我想我們可以開始做一些小工程了。”
     “好啊,沒有問題!”小P點頭。
     “但是我們在開始小的工程之前先要簡單的討論一下遞歸和有限狀態機。”老C說,“這些東東用C++的基于對象的部分完全可以應付。不過……”他打了一個哈欠。
     “嗯,時候也不早了,我們還是先閃人吧!”小P拾趣的說道。
     兩個人跑到隔壁,叫上大部隊,一邊談論最近的八卦事件一邊向大門晃去……

(遞歸?和遞推公式有關嗎?)


posted on 2009-03-11 02:59 Anderson 閱讀(1356) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


<2009年3月>
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

導航

統計

常用鏈接

留言簿(6)

隨筆檔案(21)

文章檔案(1)

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            午夜精品久久久久久久99水蜜桃| 欧美性生交xxxxx久久久| 美腿丝袜亚洲色图| 麻豆精品一区二区av白丝在线| 久久精品91久久香蕉加勒比| 欧美自拍偷拍| 毛片一区二区| 亚洲欧洲一区二区三区在线观看| 浪潮色综合久久天堂| 亚洲福利视频在线| 一本色道久久综合亚洲91| 亚洲尤物在线视频观看| 久久久国产视频91| 欧美人与性动交α欧美精品济南到 | 国产日产欧产精品推荐色 | 亚洲一级网站| 久久久久99| 亚洲人久久久| 欧美一区二区精品久久911| 美女啪啪无遮挡免费久久网站| 欧美揉bbbbb揉bbbbb| 韩国三级电影一区二区| 亚洲乱码一区二区| 久久久xxx| 一本色道久久综合亚洲精品高清| 久久国产毛片| 国产精品久久91| 黄色成人av网站| 亚洲高清三级视频| 亚洲欧美日韩一区| 久久婷婷av| 亚洲欧美国产日韩天堂区| 一本色道久久综合亚洲精品不| 欧美在线综合| 欧美视频中文字幕在线| 在线观看福利一区| 午夜老司机精品| 91久久线看在观草草青青| 香蕉免费一区二区三区在线观看| 欧美精品国产一区| 在线观看成人av电影| 久久精品日产第一区二区| 一本大道久久a久久精二百| 欧美成黄导航| 亚洲成色777777女色窝| 久久精品国产一区二区三区免费看 | 久久综合精品一区| 国产精品蜜臀在线观看| 伊人一区二区三区久久精品| 国产精品99久久久久久www| 香蕉久久久久久久av网站 | 欧美日韩亚洲一区在线观看| 国产欧美在线视频| 欧美一区二区三区视频在线观看| 欧美国产亚洲另类动漫| 久久久国际精品| 久久只有精品| 国产精品美女www爽爽爽| 夜夜爽99久久国产综合精品女不卡| 免费欧美日韩| 快she精品国产999| 亚洲欧洲一区二区天堂久久| 久久永久免费| 久久久久久一区| 亚洲第一精品在线| 国产精品永久免费在线| 欧美电影免费观看网站| 欧美一区二区三区免费观看视频| 国产精品xxxxx| 亚洲一区国产视频| 一本到12不卡视频在线dvd| 欧美屁股在线| 一区二区三区国产在线| 日韩亚洲精品电影| 国产精品激情电影| 午夜精品久久| 午夜伦理片一区| 国产日韩在线亚洲字幕中文| 久久亚洲一区二区三区四区| 久久在线免费观看| 亚洲开发第一视频在线播放| 亚洲国产精品嫩草影院| 午夜国产欧美理论在线播放| 99精品欧美一区二区三区综合在线| 欧美日韩免费看| 亚洲免费影视第一页| 性色av一区二区三区红粉影视| 国产在线观看精品一区二区三区| 亚洲免费一在线| 亚洲裸体在线观看| 国产视频久久久久| 欧美肥婆在线| 欧美日本三区| 久久精品日韩一区二区三区| 欧美jizzhd精品欧美喷水| 亚洲免费一区二区| 噜噜噜在线观看免费视频日韩 | 国产精品热久久久久夜色精品三区 | 亚洲综合99| 亚洲经典在线| 亚洲午夜激情| 亚洲激情综合| 亚洲欧洲av一区二区| 在线成人黄色| 亚洲一区国产| 亚洲精品国久久99热| 亚洲欧美中文日韩在线| 亚洲精品欧美极品| 久久精品卡一| 亚洲欧美视频| 欧美激情久久久| 美女黄色成人网| 国产精品国产三级国产aⅴ无密码| 久热精品在线视频| 国产精品美女久久久久久久 | 欧美影院久久久| 欧美/亚洲一区| 久久精品色图| 国产乱码精品一区二区三区忘忧草 | 久久久www| 欧美在线免费观看| 欧美日韩一级片在线观看| 久久久噜噜噜久久| 国产伦理一区| 亚洲已满18点击进入久久| 亚洲狼人精品一区二区三区| 久久久久五月天| 久久久久久久久蜜桃| 国产精品亚洲综合久久| 99精品国产福利在线观看免费| 亚洲激情一区二区三区| 久久久欧美一区二区| 国产欧美亚洲精品| 中文在线资源观看视频网站免费不卡| 欧美在线网站| 久久久www成人免费精品| 国产日韩欧美夫妻视频在线观看| 亚洲视频福利| 亚洲香蕉伊综合在人在线视看| 欧美成年人视频网站| 欧美xxx成人| 91久久视频| 欧美国产日韩在线| 亚洲高清123| av成人手机在线| 国产精品爱久久久久久久| 在线一区二区日韩| 午夜欧美大尺度福利影院在线看| 国产精品稀缺呦系列在线| 午夜精品久久久久久99热软件| 久久精品国产亚洲精品| 在线国产精品一区| 老司机久久99久久精品播放免费| 狼人社综合社区| 亚洲精选在线| 国产精品推荐精品| 久久精品一区二区三区不卡牛牛 | 亚洲欧美激情在线视频| 久久国产精品亚洲77777| 国语自产精品视频在线看抢先版结局 | 欧美在线免费视频| 免费不卡欧美自拍视频| 亚洲国产欧美一区二区三区久久| 欧美成人精品影院| 中文在线一区| 久久免费的精品国产v∧| 亚洲第一视频网站| 欧美日韩大片| 欧美亚洲综合网| 亚洲黄色性网站| 欧美自拍偷拍午夜视频| 亚洲人体一区| 国产午夜精品久久久久久久| 免费不卡视频| 亚洲一区三区在线观看| 欧美激情一区二区三区四区| 亚洲一区二区三区精品视频| 黄色国产精品| 国产精品爱久久久久久久| 久久夜色精品一区| 亚洲伊人观看| 亚洲电影av在线| 久久九九99视频| 亚洲一区二区三区色| 很黄很黄激情成人| 国产精品老女人精品视频| 亚洲一区二区三区精品在线观看 | av成人天堂| 国内免费精品永久在线视频| 欧美激情1区2区3区| 亚洲欧美在线视频观看| 久久精品国产一区二区三| 久久综合999| 99视频精品在线| 国产伦精品一区二区三区四区免费| 欧美成人国产| 久久手机精品视频| 欧美在线不卡视频| 亚洲欧美日韩另类精品一区二区三区| 亚洲国产日韩欧美在线图片|