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

            寶杉的博客

            UNIX/LINUX;ACE;SNMP;C++
            posts - 33, comments - 23, trackbacks - 0, articles - 0

            08-14 String類

            Posted on 2007-08-30 10:31 寶杉 閱讀(276) 評論(0)  編輯 收藏 引用 所屬分類: C++

            定義:

                 class String

                 {

                   public:

                     String(const char *str = NULL);  // 普通構造函數

                     String(const String &other);     // 拷貝構造函數

                     ~ String(void);                       // 析構函數

                     String & operate =(const String &other);  // 賦值函數

                   private:

                     char     *m_data;               // 用于保存字符串

                 };

             

             

            普通構造:

                     // String的普通構造函數

                     String::String(const char *str)

            {

                 if(str==NULL)

                 {

                     m_data = new char[1];

                     *m_data = \0;

                 }   

                 else

                 {

                     int length = strlen(str);

                     m_data = new char[length+1];

                     strcpy(m_data, str);

                 }

            }   

            注意在聲明時,才定義的參數,且賦初值為NULL。在拷貝函數內部,也進行了是否為NULL的檢查,進行特殊處理。

             

             

            析構函數:

            // String的析構函數

                     String::~String(void)

            {

                 delete [] m_data; 

            // 由于m_data是內部數據類型,也可以寫成 delete m_data;

                     }

            內部數據類型,delete

            外部數據類型,[ ] delete

             

            拷貝構造函數與賦值函數:

            拷貝函數:

            位拷貝:編譯器以此方式自動生成缺省的函數,比如構造拷貝和賦值拷貝。但是,如果函數中還有指針變量,那么缺省的函數就隱含了錯誤。

            例如:

            以類String的兩個對象a,b為例,假設a.m_data的內容為“hello”,b.m_data的內容為“world”。

            現將a賦給b,缺省賦值函數的“位拷貝”意味著執行b.m_data = a.m_data

            這將造成三個錯誤:

            一是b.m_data原有的內存沒被釋放,造成內存泄露;

            二是b.m_dataa.m_data指向同一塊內存,ab任何一方變動都會影響另一方;

            三是在對象被析構時,m_data被釋放了兩次。

            混淆:

            String  a(hello);

            String  b(world);

            String  c = a;     // 調用了拷貝構造函數,最好寫成 c(a);

            c = b;    // 調用了賦值函數

            例子:

                 // 拷貝構造函數

                 String::String(const String &other)

                 {   

            // 允許操作other的私有成員m_data

                 int length = strlen(other.m_data);  

                 m_data = new char[length+1];

                 strcpy(m_data, other.m_data);

            }

            賦值函數:

            // 賦值函數

                 String & String::operate =(const String &other)

                 {   

                     // (1) 檢查自賦值

                     if(this == &other)

                          return *this;

                    

                     // (2) 釋放原有的內存資源

                     delete [] m_data;

                    

                     // 3)分配新的內存資源,并復制內容

                 int length = strlen(other.m_data);  

                 m_data = new char[length+1];

                      strcpy(m_data, other.m_data);

                    

                     // 4)返回本對象的引用

                     return *this;

            }   

            賦值函數的四個步驟:

            (1) 檢查自賦值

            不會寫出a = a的自賦值語句,但間接自賦值有可能發生。

            // 內容自賦值

            b = a;

            c = b;

            a = c;  

            // 地址自賦值

            b = &a;

            a = *b;

            防止:

            if(this == &other)

            錯寫成為

                 if( *this == other)

            (2) 釋放原有的內存資源

            (3) 分配新的內存資源,并復制內容

            (4) 返回本對象的引用

             

            F:拷貝構造和普通構造的區別?

            Q:拷貝構造的參數是“引用”,引用不可能是NULL;普通構造函數參數是“指針”,需要類型檢查,判斷是否是NULL。

             

            String的賦值函數比構造函數復雜得多,分四步實現:

            1)第一步,檢查自賦值。你可能會認為多此一舉,難道有人會愚蠢到寫出 a = a 這樣的自賦值語句!的確不會。但是間接的自賦值仍有可能出現,例如

                

            // 內容自賦值

            b = a;

            c = b;

            a = c;  

            // 地址自賦值

            b = &a;

            a = *b;

             

            也許有人會說:“即使出現自賦值,我也可以不理睬,大不了化點時間讓對象復制自己而已,反正不會出錯!”

            他真的說錯了??纯吹诙降?span lang=EN-US>delete,自殺后還能復制自己嗎?所以,如果發現自賦值,應該馬上終止函數。注意不要將檢查自賦值的if語句

            if(this == &other)

            錯寫成為

                 if( *this == other)

            2)第二步,用delete釋放原有的內存資源。如果現在不釋放,以后就沒機會了,將造成內存泄露。

            3)第三步,分配新的內存資源,并復制字符串。注意函數strlen返回的是有效字符串長度,不包含結束符‘\0’。函數strcpy則連‘\0’一起復制。

            4)第四步,返回本對象的引用,目的是為了實現象 a = b = c 這樣的鏈式表達。注意不要將 return *this 錯寫成 return this 。那么能否寫成return other 呢?效果不是一樣嗎?

            不可以!因為我們不知道參數other的生命期。有可能other是個臨時對象,在賦值結束后它馬上消失,那么return other返回的將是垃圾。

             

             

            08-22

            如果不想讓別人使用編譯器編寫構造拷貝和賦值函數,可以聲明為私有:

                 class A

                 {

                   private:

                     A(const A &a);                   // 私有的拷貝構造函數

                     A & operate =(const A &a);  // 私有的賦值函數

                 };

             

            如果有人試圖編寫如下程序:

                 A  b(a); // 調用了私有的拷貝構造函數

                 b = a;        // 調用了私有的賦值函數

            編譯器將指出錯誤,因為外界不可以操作A的私有函數。

            但是怎樣才能使用構造拷貝和賦值函數呢?

            虛擬函數使用:C++exams\destructor

             

            在編寫派生類的賦值函數時,注意不要忘記對基類的數據成員重新賦值。例如:

            C++exams\base_operator

             

            性欧美丰满熟妇XXXX性久久久| 久久精品无码免费不卡| 中文无码久久精品| 999久久久无码国产精品| 亚洲精品国产成人99久久| 久久久久亚洲av毛片大| 人妻精品久久久久中文字幕一冢本| 精品国际久久久久999波多野| 精品欧美一区二区三区久久久| 伊人久久大香线蕉综合Av | 狠狠久久综合| 99精品国产综合久久久久五月天| 潮喷大喷水系列无码久久精品| 久久久久久国产精品美女| 国产精品久久久久国产A级| 香蕉久久AⅤ一区二区三区| 国产精品久久久久久| 一级做a爰片久久毛片毛片| 国内精品久久久久久久久| 精品久久久久久久久午夜福利| 久久这里只有精品首页| 国产精品99久久久久久董美香| 久久66热人妻偷产精品9| 区久久AAA片69亚洲| 色综合久久天天综线观看| 99久久精品免费看国产| 青青草国产精品久久久久| 久久国产精品成人影院| 午夜精品久久久久久毛片| 国产激情久久久久久熟女老人 | 久久久亚洲欧洲日产国码二区 | 久久福利青草精品资源站免费 | 久久精品中文字幕大胸| 久久人妻少妇嫩草AV无码蜜桃| 97久久精品人妻人人搡人人玩| 人妻丰满AV无码久久不卡| 久久精品国产久精国产果冻传媒 | 久久精品国产99久久久古代| 免费精品久久久久久中文字幕 | 99久久无码一区人妻a黑| 九九久久自然熟的香蕉图片|