• <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>

            第一桶 從C到C++ 第十一碗 老C初論對(duì)象模型 小P學(xué)習(xí)基于對(duì)象(之二)

                 “老C,過(guò)來(lái)幫個(gè)忙!”小P叫到。
                 “喔,什么事情?”老C正在愜意的喝著茶水消食,一邊在起點(diǎn)上翻看水文,“怎么了?”一邊說(shuō),一邊將轉(zhuǎn)椅拉到小P身邊。
                 “我不知道怎么初始化childList_……”小P指著代碼道。
                 “哦?我看看。”老C伸過(guò)脖子。

            applegame.h:

            #if !defined(APPLE_GAME_H_)
            #define APPLE_GAME_H_

            #include "childlist.h"

            class AppleGame
            {
            public:
                void play();

            private:
                enum {CHILDREN_NUM = 20U, KICK_OUT_NUM = 7U};

            private:
                bool isGameOver() const;
                void doPlay();
                int lastChildSeatNum() const;

            private:
                ChildList childList_;
            };

            #endif // APPLE_GAME_H_


                 “呵呵,你居然知道使用enum hacker這個(gè)慣用法,不錯(cuò)啊。”老C表?yè)P(yáng)小P,“那么問(wèn)題在什么地方?”
                 “我不知道如何初始化childList_,我認(rèn)為可以將 CHILDREN_NUM 作為childList_的初始化參數(shù),但是不知道在哪里調(diào)用……”小P指著代碼,“因?yàn)槲艺J(rèn)為ChildList需要這樣的構(gòu)造函數(shù)—— ChildList(int childNum)。”
                 “哦,這里你需要使用initialize list。”老C回答,然后接過(guò)鍵盤(pán),進(jìn)行了如下修改。

            applegame.h:

            #if !defined(APPLE_GAME_H_)
            #define APPLE_GAME_H_

            #include "childlist.h"

            class AppleGame
            {
            public:
                AppleGame();

                void play();

            private:
                enum {CHILDREN_NUM = 20U, KICK_OUT_NUM = 7U};

            private:
                bool isGameOver() const;
                void doPlay();
                int lastChildSeatNum() const;

            private:
                ChildList childList_;
            };

            #endif // APPLE_GAME_H_

            ------------------------------------------------------(樸實(shí)的分割線)

            applegame.cpp:

            #include "applegame.h"

            //////////////////////////////////////////////////////////////////////////
            // Public

            AppleGame::AppleGame()
            : childList_(CHILDREN_NUM)
            {
            }

                 “看,這樣就可以了。”老C解答到。“這個(gè)是關(guān)于構(gòu)造函數(shù)的一些問(wèn)題,你先繼續(xù),等程序完成了我們?cè)賮?lái)討論有關(guān)問(wèn)題。”
                 “好的。”小P回答,然后接著寫(xiě)下如下代碼。

            applegame.h:

            #if !defined(APPLE_GAME_H_)
            #define APPLE_GAME_H_

            #include "childlist.h"

            class AppleGame
            {
            public:
                AppleGame();

                void play();

            private:
                enum {CHILDREN_NUM = 20U, KICK_OUT_NUM = 7U};

            private:
                bool isGameOver() const;
                void doPlay();
                int lastChildSeatNum() const;

            private:
                ChildList childList_;
            };

            #endif // APPLE_GAME_H_

            ------------------------------------------------------(樸實(shí)的分割線)

            applegame.cpp:

            #include "applegame.h"
            #include "mydebug.h"

            #include <iostream>

            //////////////////////////////////////////////////////////////////////////
            // Public

            AppleGame::AppleGame()
            : childList_(CHILDREN_NUM)
            {
            }

            void AppleGame::play()
            {
                using namespace std;

                MY_DEBUG("Start playing game...\n");

                while (!isGameOver())
                {
                    doPlay();
                }

                cout << "The last child's seat number is: " << lastChildSeatNum() << endl;
            }


            //////////////////////////////////////////////////////////////////////////
            // Private

            bool AppleGame::isGameOver() const
            {
                return 1 == childList_.size();
            }

            void AppleGame::doPlay()
            {
                MY_DEBUG("Playing game.\n");

                childList_.countOn();
                if (KICK_OUT_NUM == childList_.currNum())
                {
                    childList_.removeCurrChild();
                }
                else
                {
                    childList_.forward();
                }
            }

            int AppleGame::lastChildSeatNum() const
            {
                int seatNum = childList_.lastChildNum();
                return seatNum;
            }

            ------------------------------------------------------(樸實(shí)的分割線)

            childlist.h:

            #if !defined(CHILD_LIST_H_)
            #define CHILD_LIST_H_

            class ChildList
            {
            public:
                ChildList(int childNum);

                int size() const;
                void countOn();
                int currNum() const;
                void removeCurrChild();
                void forward();
                int lastChildNum() const;
            };

            #endif // CHILD_LIST_H_

            ------------------------------------------------------(樸實(shí)的分割線)

            childlist.cpp:

            #include "childlist.h"

            #include "mydebug.h"

            //////////////////////////////////////////////////////////////////////////
            // Public

            ChildList::ChildList( int childNum )
            {
                MY_DEBUG_1("Create child list of %d children.\n", childNum);
            }

            int ChildList::size() const
            {
                static int n = 10;

                return --n;
            }

            void ChildList::countOn()
            {
                MY_DEBUG("Count on...\n");
            }

            int ChildList::currNum() const
            {
                static int n = 0;

                return ++n;
            }

            void ChildList::removeCurrChild()
            {
                MY_DEBUG("Remove current child from child list, then move to next child.\n");
            }

            void ChildList::forward()
            {
                MY_DEBUG("Move to next child.\n");
            }

            int ChildList::lastChildNum() const
            {
                return 10;
            }

                 “唔,照著你說(shuō)的方法,我先寫(xiě)applegame.cpp,感覺(jué)需要childList_提供什么接口的時(shí)候,就在childlist.h中聲明什么接 口。然后再加入childlist.cpp,簡(jiǎn)單的實(shí)現(xiàn)childlist.h中聲明的接口,并加入調(diào)測(cè)代碼……編譯后修改了幾處筆誤,就是現(xiàn)在這個(gè)結(jié) 果。”小P揉揉手指,叫過(guò)正在天涯上灌水的老C,對(duì)他說(shuō)道。
                 “那么你認(rèn)為程序執(zhí)行的結(jié)果如何?”老C問(wèn)道。
                 “嗯,還行。起碼證明了我的算法基本上是沒(méi)有問(wèn)題的。”小P回答。
                 “那么你就打個(gè)版本標(biāo)簽吧……不明白?就是建立一個(gè)目錄然后將代碼拷貝過(guò)去。”老C心想是不是該給小P講講配置管理相關(guān)的事情了。
                 “哦……”小P有樣學(xué)樣的建立了一個(gè)AppleGame_V3.01的目錄,然后將所有代碼拷貝了過(guò)去。
                 “好吧,現(xiàn)在你再接著實(shí)現(xiàn)child list模塊吧,有問(wèn)題叫我,”老C說(shuō)道,“我還和朋友有一些重要的事情商量……”于是他又跑去灌水了。
                
                 老C先是灌了幾篇水文,又在起點(diǎn)上看了積攢起來(lái)的幾篇更新,然后又在qq上同mm聊了會(huì)天,看看表已經(jīng)差不多2個(gè)小時(shí)了,扭過(guò)頭看看小P,好像還在鍵盤(pán)上敲敲打打。“如何?”他問(wèn)道。
                 “嗯,我已經(jīng)寫(xiě)完了,正在檢查和調(diào)試……還根據(jù)反饋的信息修改了apple game模塊和child list模塊的某些代碼。”小P答道。
                 “哦?不錯(cuò)不錯(cuò),比我想象的要快。”老C稱贊道,“要不我們來(lái)一起看看?”
                 “好!”小P應(yīng)道。

            applegame.cpp:

            #include "applegame.h"
            #include "mydebug.h"

            #include <iostream>

            //////////////////////////////////////////////////////////////////////////
            // Public

            AppleGame::AppleGame()
            : childList_(CHILDREN_NUM)
            {
            }

            void AppleGame::play()
            {
                using namespace std;

                MY_DEBUG("Start playing game...\n");

                while (!isGameOver())
                {
                    doPlay();
                }

                cout << "The last child's seat number is: " << lastChildSeatNum() << endl;
                cout << "Game Over! \n\n" << endl;
            }


            //////////////////////////////////////////////////////////////////////////
            // Private

            bool AppleGame::isGameOver() const
            {
                MY_DEBUG_1("The game has %d child now.\n", childList_.size());
                return 1 == childList_.size();
            }

            void AppleGame::doPlay()
            {
                MY_DEBUG("Playing game.\n");

                childList_.countOn();
                if (KICK_OUT_NUM == childList_.currNum())
                {
                    childList_.resetCountNum();
                    childList_.removeCurrChild();
                }
                else
                {
                    childList_.forward();
                }
            }

            int AppleGame::lastChildSeatNum() const
            {
                int seatNum = childList_.lastChildNum();
                return seatNum;
            }

            ------------------------------------------------------(樸實(shí)的分割線)

            childlist.h:

            #if !defined(CHILD_LIST_H_)
            #define CHILD_LIST_H_

            #include "list.h"

            class ChildList
            {
            public:
                ChildList(int childNum);

                int size() const;
                void countOn();
                int currNum() const;
                void resetCountNum();
                void removeCurrChild();
                void forward();
                int lastChildNum() const;

            private:
                int currCountNum_;

                List chList_;
            };

            #endif // CHILD_LIST_H_

            ------------------------------------------------------(樸實(shí)的分割線)

            childlist.cpp:

            #include "childlist.h"

            #include "mydebug.h"
            #include "list.h"
            #include <cassert>

            #include "list.h"

            //////////////////////////////////////////////////////////////////////////
            // Public

            ChildList::ChildList( int childNum )
            : currCountNum_(0)
            {
                assert(0 != childNum);

                MY_DEBUG_1("Create child list of %d children.\n", childNum);

                for (int i = 0; i < childNum; ++i)
                {
                    ListNode* newNode = new ListNode;
                    newNode->content_.seatNum_ = i + 1;
                    chList_.pushBack(newNode);
                }

                chList_.setIndex(chList_.begin());
            }

            int ChildList::size() const
            {
                return chList_.size();
            }

            void ChildList::countOn()
            {
                
                ++currCountNum_;
                MY_DEBUG_1("Count on...Current count number is %d.\n", currCountNum_);
            }

            int ChildList::currNum() const
            {
                return currCountNum_;
            }

            void ChildList::resetCountNum()
            {
                currCountNum_ = 0;
            }

            void ChildList::removeCurrChild()
            {
                MY_DEBUG("Remove current child from child list, then move to next child.\n");


                chList_.setIndex(chList_.erase(chList_.index()));
            }

            void ChildList::forward()
            {
                MY_DEBUG("Move to next child.\n");

                chList_.forward();
            }

            int ChildList::lastChildNum() const
            {
                ListNode* iter = chList_.begin();

                return iter->content_.seatNum_;
            }

            ------------------------------------------------------(樸實(shí)的分割線)

            list.h:

            #if !defined(LIST_H_)
            #define LIST_H_

            struct Child
            {
                int seatNum_;
            };

            typedef Child LIST_CONTENT;

            struct ListNode
            {
                ListNode* prev_;
                ListNode* next_;

                LIST_CONTENT content_;
            };

            class List
            {
            public:
                List();
                ~List();

                int size() const;
                void pushBack(ListNode* newNode);
                void popFront();

                void setIndex(ListNode* iter);
                ListNode* index() const;

                ListNode* begin() const;
                ListNode* end() const;
                
                void insert(ListNode* iter, ListNode* newNode);
                ListNode* erase(ListNode* iter);

                void clear();

                void forward();

            private:
                ListNode* list_;
                ListNode* index_;

                int size_;

            };

            #endif // LIST_H_

            ------------------------------------------------------(樸實(shí)的分割線)

            list.cpp:

            #include "list.h"

            #include <cstring>

            #include "mydebug.h"

            //////////////////////////////////////////////////////////////////////////
            // Public.

            List::List()
            : size_(0)
            {
                list_ = new ListNode;

                list_->prev_ = list_;
                list_->next_ = list_;
            }

            List::~List()
            {
                clear();

                memset(list_, 0, sizeof(ListNode));

                delete list_;

                list_ = 0;
            }

            int List::size() const
            {
                return size_;
            }

            void List::pushBack( ListNode* newNode )
            {
                insert(end(), newNode);
            }

            void List::popFront()
            {
                if (size())
                {
                    erase(begin());
                }    
            }

            void List::setIndex( ListNode* iter )
            {
                index_ = iter;
            }

            ListNode* List::index() const
            {
                return index_;
            }

            ListNode* List::begin() const
            {
                return list_->next_;
            }

            ListNode* List::end() const
            {
                return list_;
            }

            void List::insert( ListNode* iter, ListNode* newNode )
            {
                newNode->next_            = iter;
                newNode->prev_            = iter->prev_;
                newNode->prev_->next_    = newNode;
                newNode->next_->prev_    = newNode;

                ++size_;
            }

            ListNode* List::erase( ListNode* iter )
            {
                MY_DEBUG_1("The node erased is %d.\n", iter->content_.seatNum_);
                
                ListNode* it = iter->next_;

                if (end() == it)
                {
                    it = begin();
                }
                
                iter->prev_->next_ = iter->next_;
                iter->next_->prev_ = iter->prev_;

                memset(iter, 0, sizeof(ListNode));

                delete iter;

                --size_;    

                return it;
            }

            void List::clear()
            {
                while (size())
                {
                    popFront();
                }
            }

            void List::forward()
            {
                index_ = index_->next_;

                if (end() == index_)
                {
                    index_ = begin();
                }
            }

                 “嗯,很不錯(cuò),”老C稱贊道,“知道要使用initialize list初始化成員變量,知道要在構(gòu)造函數(shù)中初始化linked list的head,還知道在析構(gòu)函數(shù)中釋放內(nèi)存……”老C由衷的說(shuō),“你還是知道一些編程的技巧的啊。”
                 “呵呵,以前本科的時(shí)候稍微學(xué)習(xí)過(guò)一些,哈哈。”小P謙虛道,“不過(guò)大部分代碼還是參考你以前C版本的實(shí)現(xiàn),我只不過(guò)是改良了一小部分而已。”
                 “哦,不要小看改良的一小部分,如果在正確的道路上日積月累,這種變化累積起來(lái)效果還是很顯著的。”老C道,“說(shuō)說(shuō)你經(jīng)過(guò)編碼和調(diào)試后,現(xiàn)在的感覺(jué)吧。”
                 “嗯……我就說(shuō)說(shuō)問(wèn)題吧——好的就不說(shuō)了,都是相似的——首先,感覺(jué)這種編碼方式有些繁雜,需要在幾個(gè)文件中跳來(lái)跳去的;其次,我在編寫(xiě)list模塊的時(shí) 候感覺(jué)index是個(gè)很煩人的東西,恨不得將它變?yōu)閜ublic的……目前的體會(huì)也就這么多。”小P一邊想一邊說(shuō)道,“噢,對(duì)了,還有關(guān)于list,怎么 樣才可以寫(xiě)好這個(gè)類呢?”小P又補(bǔ)充道。
                 “你體會(huì)的挺深刻的啊,”老C點(diǎn)點(diǎn)頭,“你說(shuō)的沒(méi)有錯(cuò),如果照這種方式寫(xiě)代碼的確有些繁雜,因?yàn)檫@個(gè)工作不應(yīng)當(dāng)直接在編碼過(guò)程中進(jìn)行,而應(yīng)當(dāng)在設(shè)計(jì)過(guò)程中 進(jìn)行。要解決這個(gè)問(wèn)題,需要引入新的工具——UML……等會(huì)再給你解釋什么是UML……”制止住小P的發(fā)問(wèn),老C接著說(shuō),“確實(shí),將index放在 list內(nèi)部會(huì)造成種種不便,但是也有解決之道,比較經(jīng)典的做法是將index從list中拿出來(lái)單獨(dú)成為一個(gè)模塊或class,這就是iterator 設(shè)計(jì)模式,我們以后再慢慢說(shuō)……”他停頓了一下,“至于怎么良好的設(shè)計(jì)list,也有一些經(jīng)驗(yàn)可以總結(jié),同時(shí)也有一些業(yè)內(nèi)的慣用法,這個(gè)我們接下來(lái)會(huì)更早 討論這個(gè)問(wèn)題。”
                 “噢?那么我應(yīng)當(dāng)先學(xué)習(xí)什么呢?”小P問(wèn)。
                 “嗯,先接觸一下UML,”老C想想說(shuō)道,“然后我給你講講一些關(guān)于線性表的慣用法或者習(xí)語(yǔ)。最后我們?cè)賮?lái)討論如何將index與它的操作從list中拿出來(lái)。”
                 “好哩。”小P高興的說(shuō)道。
                 “呵呵,現(xiàn)在我們終于有了一個(gè)用C++實(shí)現(xiàn)的穩(wěn)定版本,我們就叫它4.0吧。”老C建議。
                 “好啊。”小P同意,于是他建立了一個(gè)AppleGame_V4.0的目錄,將所有代碼拷貝進(jìn)去。
                 “現(xiàn)在我們進(jìn)入到C++編程學(xué)習(xí)的階段,”老C道,“你要試著從C過(guò)渡到C++,在轉(zhuǎn)換過(guò)程中有一些細(xì)節(jié)上的事情需要注意一下。”
                 “哦?哪些事情?”小P問(wèn)。
                 “包括以const、enum和inline替換#define,盡量使用const等等細(xì)節(jié),我強(qiáng)烈建議你看看《Effective C++ Third Edition》的第一章,里面有很詳細(xì)的介紹,不過(guò)在此之前我根據(jù)我們的代碼簡(jiǎn)單的提示一下。”老C回答道,“這本書(shū)后面的章節(jié)可能有些深入,如果你不 想看也無(wú)所謂,反正還不是時(shí)候。”他又補(bǔ)充了一句。
                 “好,我仔細(xì)研究一下那個(gè)什么書(shū)……”小P回答。
                 “囧。”決定無(wú)視這個(gè)什么都不知道的小正太的天真問(wèn)題,老C直接指著代碼問(wèn)道,“你知道這聲明最后的const是什么含義嗎?”

            class AppleGame
            {
            public:
                AppleGame();

                void play();

            private:
                enum {CHILDREN_NUM = 20U, KICK_OUT_NUM = 7U};

            private:
                bool isGameOver() const;
                void doPlay();
                int lastChildSeatNum() const;

            private:
                ChildList childList_;
            };

                 “因?yàn)閕sGameOver()函數(shù)沒(méi)有對(duì)AppleGame類中的任何數(shù)據(jù)進(jìn)行操作,所以將它聲明為const,怎么?有什么問(wèn)題嗎?”
                 “沒(méi)有,我只是想和你詳細(xì)討論一下。在這isGameOver()被聲明為const是很好的,但是我想說(shuō)明一下背后發(fā)生了什么。”老C又拉過(guò)白板,指揮小P在上面擦出一塊空白區(qū)域,然后寫(xiě)下幾行文字。

            C++:
            class AppleGame
            {
            public:
                ...
            private:
                bool isGameOver() const;
                ...
            };

            用C翻譯:
            struct AppleGame
            {
            public:
                ...
            private:
                ...
            };

            bool AppleGame::isGameOver(const AppleGame* this);

                 “這下你明白函數(shù)聲明后面的const是什么意思了吧?”老C問(wèn)。
                 “哦,這樣看來(lái)就清楚多了,怪不得isGameOver()函數(shù)不能對(duì)AppleGame類中的數(shù)據(jù)進(jìn)行操作,原來(lái)是這么回事。”小P道。
                 “呵呵,在這里寫(xiě)這段代碼是想提醒你盡量使用const,并且要確保const的正確性,因?yàn)椴宦暶鳛閏onst,就是你認(rèn)為不需要const。”老C接著問(wèn)道,“你可以簡(jiǎn)單的解釋一下const嗎?”
                 “就是表示常量……”
                 “嘿,業(yè)余了吧。”還沒(méi)有等到小P說(shuō)完,老C就打斷了他,“其實(shí)const表示的是只讀,而不完全是常量!”
                 “哦……呵呵,現(xiàn)在我知道了,也算變得職業(yè)一些了吧……對(duì)了,周末說(shuō)說(shuō)那個(gè)什么UML如何?反正快國(guó)慶了,趁著假期可以看看。”小P道。
                 “哦?你國(guó)慶不陪女朋友出去玩玩?據(jù)我所知你女朋友很漂亮的,要知道女人是要經(jīng)常陪的……”老C開(kāi)始給小P介紹自己的慘痛經(jīng)驗(yàn)。
                 “哈哈,合理安排時(shí)間,相互不沖突,不沖突……”小P笑著回答。
                 兩個(gè)人說(shuō)說(shuō)笑笑,收拾東西,離開(kāi)了教研室。

            (下面就進(jìn)入C++階段啦,請(qǐng)關(guān)注第二桶 基于對(duì)象)


            posted on 2009-02-20 20:02 Anderson 閱讀(1583) 評(píng)論(4)  編輯 收藏 引用

            評(píng)論

            # re: 第一桶 從C到C++ 第十一碗 老C初論對(duì)象模型 小P學(xué)習(xí)基于對(duì)象(之二) 2009-02-20 22:11 ry

            高手,有空去我網(wǎng)站做作
            http://www.571sd.cn
            你的建站專家  回復(fù)  更多評(píng)論   

            # re: 第一桶 從C到C++ 第十一碗 老C初論對(duì)象模型 小P學(xué)習(xí)基于對(duì)象(之二)[未登錄](méi) 2009-02-22 10:11 笨笨

            寫(xiě)得不錯(cuò)啊,很深刻。
            適合于已經(jīng)學(xué)習(xí)了C語(yǔ)言,對(duì)C++也有些了解的人讀  回復(fù)  更多評(píng)論   

            # re: 第一桶 從C到C++ 第十一碗 老C初論對(duì)象模型 小P學(xué)習(xí)基于對(duì)象(之二)[未登錄](méi) 2009-02-22 11:27 崔友志

            循序漸進(jìn) 很有條理  回復(fù)  更多評(píng)論   

            # re: 第一桶 從C到C++ 第十一碗 老C初論對(duì)象模型 小P學(xué)習(xí)基于對(duì)象(之二) 2009-02-23 17:57 崇拜阿

            崇拜阿,什么出書(shū)?  回復(fù)  更多評(píng)論   


            只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


            <2009年2月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            1234567

            導(dǎo)航

            統(tǒng)計(jì)

            常用鏈接

            留言簿(6)

            隨筆檔案(21)

            文章檔案(1)

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            一本一道久久精品综合| 99久久国产主播综合精品| 久久久WWW免费人成精品| 亚洲va久久久噜噜噜久久天堂| 国产精品免费久久久久久久久 | 亚洲国产香蕉人人爽成AV片久久| 久久久久亚洲AV成人片| 波多野结衣AV无码久久一区| 色99久久久久高潮综合影院| 精品乱码久久久久久夜夜嗨| 久久这里只精品国产99热| 久久人爽人人爽人人片AV | 精品国产91久久久久久久a| 久久中文精品无码中文字幕| 国产精品久久久久久久久久免费| 性做久久久久久久久久久| 久久婷婷五月综合97色一本一本 | 99久久精品国产一区二区 | 午夜精品久久久久久99热| 久久亚洲国产欧洲精品一| 久久婷婷五月综合色奶水99啪| 国产精品久久久久久福利69堂| 国产精品99久久免费观看| 国内精品久久久久影院日本| 久久亚洲电影| 久久香蕉国产线看观看99| 成人综合久久精品色婷婷| 93精91精品国产综合久久香蕉| 五月丁香综合激情六月久久| 久久久久亚洲AV成人网| 久久国产乱子伦免费精品| 久久无码国产专区精品| 久久93精品国产91久久综合| 99久久人妻无码精品系列蜜桃| 精品久久久久久久久免费影院 | 国产伊人久久| 国产精品美女久久久久网| 久久久久亚洲精品无码蜜桃| 久久久久亚洲AV无码专区首JN | 97久久综合精品久久久综合| 亚洲熟妇无码另类久久久|