/*********************
    WZ  ASUST
写实拷贝
注意每一个重载的操作
修改一个对象的操作均需要构造空间
S[2]='S'怎样传参数
*********************/

#include"sts.h"
 class String
{
public:
     String(char *str = "")
      :_str(new char[strlen(str) + 5])
     {
          *(int *)_str = 1;
          _str += 4;
          strcpy(_str, str);
     }
     ~String()
     {
          if (_str != NULL)
          {
              _clear();
          }
     }
     String(const String& str)
     {
          _str = str._str;
          ++_GetRefCount();
     }
     String& operator=(const String& str)
     {
          if (this != &str)
          {
               _clear();
               _str = str._str;
               ++ _GetRefCount();
          }
          return *this;
     }
     char& operator[](int index)//写时拷贝
     {
 
          if (_GetRefCount()>1)//当引用次数大于1时新开辟内存空间
          {
               --_GetRefCount();//原来得空间引用计数器减1
               char *str = new char[strlen(_str) + 5];
               strcpy(str+4, _str);
               _str = str+4;
               _GetRefCount()++;
          }
          return _str[index];
     }
     friend ostream& operator<<(ostream& output, const String& str)
     {
          output << str._str<<endl;
          return output;
     }
 
private:
     int& _GetRefCount()
     {
          return *(int *)(_str - 4);
     }
     void _clear()
     {
          if (--_GetRefCount() == 0)
          {
               delete[] (_str-4);
          }
     }
private:
     char *_str;
};

int main()
{
String s1("123");
String s2(s1);
String s3("1234");
cout<<s1;
cout<<s2;
s2=s3;
cout<<s2;
cout<<s3;
return 0;
}