#include<iostream>
using namespace std;
class String
{
public:
String(const char*str = "")
:_str(new char[strlen(str) + 5])
{
_str += 4;
strcpy(_str, str);
_GetRefCount(_str) = 1;
}
String(String &s)
:_str(s._str)
{
++_GetRefCount(_str);
}
String& operator=(const String&s)
{
if (this != &s)
{
this->_Release();
_str = s._str;
++_GetRefCount(_str);
}
return *this;
}
char& operator[](size_t index)
{
if (_GetRefCount(_str) > 1)
{
_Release();
char*tmp = new char[strlen(_str) + 5];
tmp += 4;
strcpy(tmp, _str);
_GetRefCount(tmp) = 1;
_str = tmp;
}
return _str[index];
}
~String()
{
_Release();
}
private:
int& _GetRefCount(char*ptr)
{
return *(int*)(ptr - 4);
}
void _Release()
{
if (--_GetRefCount(_str) == 0)
{
delete[](_str - 4);
}
}
friend ostream& operator<<(ostream& os, const String& s);
private:
char* _str;
};
ostream& operator<<(ostream& os, const String& s)
{
os << s._str;
return os;
}
void Test0()
{
String s1("abcd");
String s2(s1);
cout << "s1:" << s1 << endl;
cout << "s2:" << s2 << endl;
String s3("efgh");
s3 = s2;
cout << "s3:" << s3<< endl;
}
void Test1()
{
String s1("abcd");
String s2(s1);
s2[0] = 'x';
s2[3] = 'x';
String s3(s2);
String s4(s1);
cout << "s1:" << s1 << endl;
cout << "s2:" << s2 << endl;
cout << "s3:" << s3 << endl;
cout << "s4:" << s4 << endl;
}
int main()
{
//Test0();
Test1();
return 0;
}