• <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>
            OnTheWay2012
            埋葬昨天的我,迎來重生的我!
            posts - 15,  comments - 89,  trackbacks - 0

            http://m.shnenglu.com/Tveiker/archive/2011/01/08/138154.aspx本鏈接是“隨筆”寫的一篇名叫《鏈表實(shí)驗(yàn)》的文章,以下是我的分析。

            我理解你說的學(xué)號(hào)的問題是:一個(gè)叫X是男性年齡是22歲的學(xué)生,假設(shè)其學(xué)號(hào)是2009000,把該學(xué)生加入到鏈表之后,該學(xué)生的
            學(xué)號(hào)發(fā)生了變化,不再是2009000。

            如果你所說的學(xué)號(hào)問題和上面的描述一致的話,該問題產(chǎn)生的原因是:Student類不應(yīng)該有拷貝構(gòu)造函數(shù)和賦值函數(shù)。
             假如為了實(shí)現(xiàn)Student類與STL容器搭配使用的能力(要獲得此種能力Student必須有拷貝構(gòu)造函數(shù)和其他一些函數(shù)根據(jù)你所使用到的容器
             和算法所要求的特殊函數(shù),例如operator<)的話,這兩個(gè)函數(shù)也應(yīng)該換種寫法,為了實(shí)現(xiàn)此種能力這兩個(gè)函數(shù)有以下實(shí)現(xiàn)方法:
             (1)學(xué)號(hào)的轉(zhuǎn)移,參考STL的auto_ptr的控制權(quán)轉(zhuǎn)移策略

             以上是對(duì)你碰到問題的說明,另外從你所寫的代碼中還發(fā)現(xiàn)了一些問題和不足之處,具體詳述如下:
             問題
              (1)Student的構(gòu)造函數(shù)(Student()、Student(char *name,char* sex,int age))沒有把next初始化
              (2)Student的拷貝構(gòu)造函數(shù)沒有進(jìn)行if (this != &s)的判斷
              (3)Student類中的Name、Sex可以不使用char*類型(之所以把這個(gè)情況說成是問題而不是不足之處是為了以后寫代碼是少犯與指針相關(guān)的錯(cuò)誤)
              (4)在Student類的析構(gòu)函數(shù)中不能對(duì)寫“Stu_no--;”這樣的語句,如果想實(shí)現(xiàn)學(xué)號(hào)重用的能夠的話就需要記錄學(xué)號(hào)的使用情況(本文不討論此問題)

             不足之處
              (1)形如class Student{
              的代碼風(fēng)格不好,應(yīng)該修改為
              class Student
              {
              (2)學(xué)號(hào)不應(yīng)該是一個(gè)整數(shù)并且應(yīng)該隱藏學(xué)號(hào)這一重要對(duì)象的生成方式(因?yàn)閷W(xué)號(hào)很可能每個(gè)學(xué)校不一樣,為了應(yīng)對(duì)變化,所以對(duì)可能發(fā)生變化
                的地方進(jìn)行封裝)
              (3)Student類不應(yīng)該包含next指針
              (4)Link類中的Add函數(shù)的接口設(shè)計(jì)很不合理(在使用的時(shí)候需要先構(gòu)造出一個(gè)Student,這很沒有必要)
              (5)Link類中的pivot作為類的成員變量不太合適并且沒有多大意義

            提醒你一下:請(qǐng)仔細(xì)思考拷貝構(gòu)造函數(shù)的意義,拷貝構(gòu)造的意義簡(jiǎn)單來說就是克隆,而你寫的代碼沒有克隆好,所以的導(dǎo)致了學(xué)號(hào)問題
            針對(duì)上述所有問題的修改方案有三種
            (1)A方案:禁止拷貝構(gòu)造
            (2)B方案:學(xué)號(hào)轉(zhuǎn)移 非法學(xué)號(hào)
            各個(gè)方案的實(shí)現(xiàn)方法如下,其中對(duì)于學(xué)號(hào)的生成方法這二種方案都一樣(為了簡(jiǎn)單起見,學(xué)號(hào)仍然采用整數(shù))

             1/************************************************************************/
             2/*                          學(xué)號(hào)生成                                    */
             3/************************************************************************/
             4
             5typedef int StudentID;
             6
             7class StudentIDGenerate
             8{
             9public:
            10    static StudentID GenerateID()
            11    {
            12        return StudentBaseID++;
            13    }

            14
            15private:
            16    static StudentID StudentBaseID;
            17}
            ;
            18
            19StudentID StudentIDGenerate::StudentBaseID = 2009000;
            20
            21/************************************************************************/
            22/*                            鏈表節(jié)點(diǎn)                                  */
            23/************************************************************************/
            24template <typename T>
            25struct LinkNode
            26{
            27    T m_value;
            28    LinkNode<T> *m_pNext;
            29
            30    LinkNode() : m_pNext(NULL)
            31    {
            32
            33    }

            34}
            ;
            以上是通用代碼,下面是方案A的代碼
              1/************************************************************************/
              2/*                       A方案                                          */
              3/************************************************************************/
              4
              5class Student
              6{
              7    friend class Link;
              8
              9public:
             10    Student();
             11    Student(string const &strName,string const &strSex, int nAge);
             12    ~Student();
             13
             14public:
             15    void display();
             16    void SetValue(string const &strName,string const &strSex, int nAge);
             17    int GetAge() const;
             18
             19private://通過把以下函數(shù)設(shè)置為私有來實(shí)現(xiàn)禁止拷貝構(gòu)造的能力
             20    Student(const Student &);
             21    Student &operator=(const Student &s);
             22
             23private:
             24    string m_strName;
             25    int m_nAge;
             26    string m_strSex;
             27    StudentID m_ID;
             28}
            ;
             29
             30typedef LinkNode<Student> StudentNode;
             31
             32Student::Student()
             33{
             34    m_ID = StudentIDGenerate::GenerateID();
             35    m_nAge = 0;
             36}

             37
             38Student::Student(string const &strName,string const &strSex,int nAge)
             39{
             40    m_strName = strName;
             41    m_strSex = strSex;
             42    m_ID = StudentIDGenerate::GenerateID();
             43    m_nAge = nAge;
             44}

             45
             46Student::Student(const Student &s)
             47{
             48    assert(false);
             49}

             50
             51Student &Student::operator =(const Student &s)
             52{
             53    assert(false);
             54    return *this;
             55}

             56
             57Student::~Student()
             58{
             59    
             60}

             61
             62void Student::display() 
             63{
             64    cout<<"Name is:"<<m_strName<<"    ID is:"<<m_ID<<"    Sex is:"<<m_strSex<<"    Age is:"<<m_nAge<<endl;
             65}

             66
             67void Student::SetValue(string const &strName,string const &strSex, int nAge)
             68{
             69    m_strName = strName;
             70    m_strSex = strSex;
             71    m_nAge = nAge;
             72}

             73
             74int Student::GetAge() const
             75{
             76    return m_nAge;
             77}

             78
             79class Link
             80{
             81public:
             82    Link();
             83    ~Link();
             84
             85public:
             86    void Delete(StudentID);
             87    void Add(string const &strName,string const &strSex,int nAge);
             88    void Display();
             89
             90private:
             91    StudentNode *m_pHead;
             92    StudentNode *m_pTail;
             93}
            ;
             94
             95Link::Link()//構(gòu)造空鏈表
             96{
             97    m_pHead=NULL;
             98    m_pTail=NULL;
             99}

            100
            101Link::~Link()//釋放內(nèi)存
            102{
            103    while (NULL != m_pHead)
            104    {
            105        StudentNode *pTemp = m_pHead;
            106        m_pHead = m_pHead->m_pNext;
            107        delete pTemp;
            108    }

            109}
                
            110
            111void Link::Add(string const &strName,string const &strSex,int nAge)//向鏈表中添加學(xué)生
            112{
            113    if(m_pHead==NULL)
            114    {
            115        m_pHead = new StudentNode();
            116        m_pHead->m_value.SetValue(strName, strSex, nAge);
            117        m_pTail = m_pHead;
            118        m_pTail->m_pNext = NULL;
            119    }

            120    else
            121    {
            122        m_pTail->m_pNext = new StudentNode;
            123        m_pTail->m_pNext->m_value.SetValue(strName, strSex, nAge);
            124        m_pTail->m_pNext->m_pNext = NULL;
            125        m_pTail = m_pTail->m_pNext;
            126    }

            127}

            128
            129void Link::Display()//顯示鏈表中學(xué)生信息
            130{
            131    cout<<endl;
            132    StudentNode *pTemp = m_pHead;
            133    while (NULL != pTemp)
            134    {
            135        pTemp->m_value.display();
            136        pTemp = pTemp->m_pNext;
            137    }

            138    cout<<endl;
            139}

            140
            141void Link::Delete(int nAge)//刪除鏈表中所有年齡為nAge的學(xué)生
            142{
            143    StudentNode *pPre = m_pHead;
            144    StudentNode *pCur = m_pHead;
            145    while (NULL != pCur)
            146    {
            147        if (pCur->m_value.GetAge() == nAge)
            148        {
            149            if (pCur == m_pHead)
            150            {
            151                pPre = m_pHead = m_pHead->m_pNext;
            152            }

            153            else
            154            {
            155                pPre->m_pNext = pCur->m_pNext;
            156            }

            157            
            158            pCur->m_value.display();
            159            delete pCur;
            160            pCur = NULL != pPre ? pPre->m_pNext : NULL;
            161        }

            162        else
            163        {
            164            pPre = pCur;
            165            pCur = pCur->m_pNext;
            166        }

            167    }

            168}
            以下是測(cè)試方案A的代碼
            void main()
            {
                
            //測(cè)試零
                
            //vector<Student> vecStu;
                
            //Student st1;
                
            //vecStu.push_back(st1);

                
            //Student st2;
                
            //vecStu.push_back(st2);

                
            //測(cè)試一
                Link link;
                link.Add(
            "X","Boy",22);
                link.Add(
            "Y","Boy",20);
                link.Add(
            "Z","Boy",21);
                link.Add(
            "U","Girl",22);
                
                link.Display();
                link.Delete(
            21);
                
                link.Display();

                
            //測(cè)試二
                Link link1;
                link1.Add(
            "X","Boy",22);
                link1.Add(
            "Y","Boy",20);
                link1.Add(
            "Z1","Boy",21);
                link1.Add(
            "Z2","Boy",21);
                link1.Add(
            "U","Girl",22);

                link1.Display();
                link1.Delete(
            21);

                link1.Display();

                
            //測(cè)試三
                Link link2;
                link2.Add(
            "X","Boy",22);
                link2.Add(
            "Y","Boy",20);
                link2.Add(
            "Z1","Boy",21);
                link2.Add(
            "Z2","Boy",21);
                link2.Add(
            "U","Girl",22);

                link2.Display();
                link2.Delete(
            22);

                link2.Display();

                
            //測(cè)試四
                Link link3;
                link3.Add(
            "X","Boy",22);
                
                link3.Display();
                link3.Delete(
            22);

                link3.Display();

                
            //測(cè)試五
                Link link4;
                link4.Add(
            "X","Boy",22);
                link4.Add(
            "Y","Boy",20);
                link4.Add(
            "Z1","Boy",21);
                link4.Add(
            "Z2","Boy",21);
                link4.Add(
            "U","Girl",22);

                link4.Display();
                link4.Delete(
            1);

                link4.Display();
            }
            其中采用方案A是測(cè)試零下面所注釋掉的代碼不能通過編譯,在VC2008的IDE下會(huì)報(bào):class“Student”: 沒有可用的復(fù)制構(gòu)造函數(shù)或復(fù)制構(gòu)造函數(shù)聲明為“explicit”錯(cuò)誤

            為了修正此錯(cuò)誤,對(duì)代碼就行了修改,也就是B方案
            const StudentID ErrorStudentID = 0;//其實(shí)非法學(xué)號(hào)是個(gè)范圍[負(fù)無窮,2009000]   添加的代碼
            mutable StudentID m_ID;//為了能夠在拷貝構(gòu)造函數(shù)中修改該值,把其類型聲明為mutable  修改的代碼

            //修改的代碼
            Student::Student(const Student &s)
            {
                m_strName 
            = s.m_strName;
                m_strSex 
            = s.m_strSex;
                m_ID 
            = s.m_ID;
                s.m_ID 
            = ErrorStudentID;
                m_nAge 
            = s.m_nAge;
            }


            //修改的代碼
            Student &Student::operator =(const Student &s)
            {
                
            if (this != &s)
                
            {
                    m_strName 
            = s.m_strName;
                    m_strSex 
            = s.m_strSex;
                    m_ID 
            = s.m_ID;
                    s.m_ID 
            = ErrorStudentID;
                    m_nAge 
            = s.m_nAge;
                }


                
            return *this;
            }

            PS:
            使用面向?qū)ο笳Z言進(jìn)行程序設(shè)計(jì)的時(shí)候一個(gè)關(guān)鍵的問題是:設(shè)計(jì)一個(gè)好的類,這里的Student類就是一個(gè)典型的例子。
            學(xué)習(xí)的時(shí)候當(dāng)然可以自己寫個(gè)鏈表,自己管理內(nèi)存;但是在實(shí)際工作中還是要多用STL現(xiàn)成的容器和算法,只有這樣才能提高代碼的質(zhì)量,降低錯(cuò)誤發(fā)生的概率。
            上面代碼實(shí)際還可以繼續(xù)進(jìn)行改進(jìn),不夠?qū)懙来朔N程度基本上沒有什么大問題了。
            posted on 2011-01-09 07:45 OnTheWay 閱讀(1623) 評(píng)論(2)  編輯 收藏 引用 所屬分類: 個(gè)人感悟

            FeedBack:
            # re: 對(duì)“隨筆”所寫的一篇文章《鏈表實(shí)驗(yàn)》的一點(diǎn)看法
            2011-01-09 11:17 | あ維wêiセ
            謝謝咯,呵呵。我喜歡這代碼風(fēng)格,向你學(xué)習(xí)  回復(fù)  更多評(píng)論
              
            # re: 對(duì)“隨筆”所寫的一篇文章《鏈表實(shí)驗(yàn)》的一點(diǎn)看法
            2011-01-09 19:58 | 陳梓瀚(vczh)
            我認(rèn)為問題只需要修改成,只將某一個(gè)指定的vector<Student>里面的Student實(shí)例視為合法實(shí)例就好了。其他地方存放的Student都是非法的,但是不禁止復(fù)制,只是復(fù)制后改了也沒用的意思。  回復(fù)  更多評(píng)論
              

            <2025年6月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            293012345

            常用鏈接

            留言簿(4)

            隨筆分類

            隨筆檔案

            友情連接

            搜索

            •  

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            99精品伊人久久久大香线蕉 | 人人狠狠综合88综合久久| 日韩十八禁一区二区久久 | 久久久国产视频| 久久青青草原精品国产| 久久av高潮av无码av喷吹| 久久精品人人槡人妻人人玩AV | 日韩久久久久中文字幕人妻| 婷婷久久久亚洲欧洲日产国码AV| 亚洲嫩草影院久久精品| 一本久久知道综合久久| 深夜久久AAAAA级毛片免费看| 久久精品国产网红主播| 热99RE久久精品这里都是精品免费| 久久久青草青青亚洲国产免观| 久久精品国产亚洲AV影院| 精品国产综合区久久久久久| 国产产无码乱码精品久久鸭 | 国产A级毛片久久久精品毛片| 国产精品久久久天天影视香蕉| 久久国产精品无码一区二区三区| 亚洲国产成人久久一区久久| A级毛片无码久久精品免费| 丰满少妇人妻久久久久久| 亚洲va久久久噜噜噜久久狠狠| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 夜夜亚洲天天久久| 精品久久一区二区三区| 少妇精品久久久一区二区三区 | 精品久久久无码人妻中文字幕豆芽| 欧美激情一区二区久久久| 人人狠狠综合88综合久久| 久久久久九国产精品| 国产亚洲精午夜久久久久久| 99久久人人爽亚洲精品美女| 青青青青久久精品国产h| 国产精品美女久久久| 国产精品天天影视久久综合网| 国产精品国色综合久久| 久久久精品免费国产四虎| 亚洲国产精久久久久久久|