寫時拷貝(方案四)

方案四

class String
{
   private:
           char* _str;
};

wKiom1b03ZmQGBzTAAAhoeram48598.png

方案四與方案三類似。方案四把用來計數的整形變量放在所開闢的內存空間的首部,

用*((int*)_str)就能來改變計數值

class String
{
public:
           String(char * str = "" )    //不能strlen(NULL)
           {
                    _str = new char[strlen( str) + 5];
                    _str += 4;
                    strcpy(_str, str);
                    GetRefCount(_str) = 1;
           }
           String(const String &s)
           {
                    _str = s._str;
                    ++GetRefCount(_str);
           }

           //要考慮是s1=s2時,s1原先不爲空的情況,要先釋放原內存
           //如果要釋放原內存時,要考慮它的_refCount減1後是否爲0,
           //爲零再釋放,否則其它對象指針無法再訪問這片空間
           String& operator=(String& s)
           {
                    if (this != &s )
                    {
                              if (GetRefCount(_str ) == 1)
                              {
                                       delete (_str-4);
                                       _str = s._str;
                                       ++GetRefCount(_str );
                              }
                              else
                              {
                                       --GetRefCount(_str );
                                       _str = s._str;
                                       ++GetRefCount(_str );
                              }
                    }
                    return *this ;
           }
           //如果修改了字符串的內容,那所有指向這塊內存的對象指針的內容間接被改變
           //如果還有其它指針指向這塊內存,我們可以從堆上重新開闢一塊內存空間,
           //把原字符串拷貝過來.
           //再去改變它的內容,就不會產生鏈式反應
           
         
           char& String ::operator[](const size_t index ) //深拷貝     
           {
                   
                              if (GetRefCount(_str) == 1)
                              {
                                       return _str[index ];
                              }
                              else
                              {
                                        //  1.減引用計數
                                       --GetRefCount(_str );
                                        //  2.拷貝     3.創建新的引用計數
                                       char* tmp = new char [strlen(_str) + 5];   
                                      *((int *)tmp) = 1;
                                       tmp += 4;
                                       strcpy(tmp, _str);
                                       _str = tmp;
                                       return _str[index ];
                              }
           }

           int& GetRefCount(char* ptr)    //獲取引用計數(隱式內聯函數)
           {
                    return *((int *)(ptr -4));
           }
           ~String()
           {
                    if (--GetRefCount(_str) == 0)
                    {
                              cout << "~String" << endl;
                              delete[] (_str-4);             
                    }
          
           }
           
private:
           char* _str;

};

以下是其它方案鏈接地址:

方案一:

http://iynu17.blog.51cto.com/10734157/1755179

方案二:

http://iynu17.blog.51cto.com/10734157/1755185

方案三:

http://iynu17.blog.51cto.com/10734157/1755208


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章