第一种:
只采用_str一个变量,利用强制转换前后偏移,获取存取计数的位置,以及存放字符串的位置。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
class String
{
public:
String(char* str = "")
:_str(new char[strlen(str) + 5])
{
*(int*)_str = 1;
_str += 4;
strcpy(_str, str);
}
String(const String& s)
:_str(s._str)
{
++(*(int*)(_str - 4));
}
//重载=
String& operator= (const String& s)
{
if (s._str != _str)
{
Release();
_str = s._str;
}
return *this;
}
//重载[]
char& operator[] (size_t index)
{
if (GetRefCount(_str) >1)
{
char* tmp = new char[strlen(_str) + 5];
tmp += 4;
GetRefCount(tmp) = 1;
strcpy(tmp, _str);
--(GetRefCount(_str));
_str = tmp;
}
return _str[index];
}
~String()
{
Release();
}
void Release()
{
if (*(int*)(_str) == 0)
{
delete[] (_str - 4);//指针返回首地址位置,释放整段空间
}
}
int& GetRefCount(char* str)
{
return *(int*)(_str - 4);
}
private:
char* _str;
};
void Test()
{
String s1("xxxxxxxxxxxxxx");
String s2(s1);
s2 = s1;
String s3("yyyyyyy");
String s4(s3);
s4 = s3;
s3 = s1;
s3[0] = 'S';
}
int main()
{
Test();
system("pause");
return 0;
}
第二种:
采用_str以及_pRefCount两个变量。
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
class String
{
public:
String(char* str = "")
:_str(new char[strlen(str) + 1])
, _pRefCount(new int(1))
{
strcpy(_str, str);
}
String(String& s)
:_str(s._str)
, _pRefCount(s._pRefCount)
{
++(*_pRefCount);
}
String& operator=(const String& s)
{
/*if(_str != s.str)
{
if (--(*_pRefCount) == 0)
{
delete[] _str;
delete _pRefCount;
}
_str = s._str;
_pRefCount = s._pRefCount;
++(*_pRefCount);
}
return *this;*/
if (_str != s._str)
{
if (--(*_pRefCount) == 0)
{
Release();
}
_str = s._str;
_pRefCount = s._pRefCount;
++(*_pRefCount);
}
return *this;
}
~String()
{
/*if (--(*_pRefCount) == 0)
{
delete[] _str;
delete _pRefCount;
}*/
Release();
}
void Release()
{
if (--(*_pRefCount) == 0)
{
delete[] _str;
delete _pRefCount;
}
}
//与测试函数2对应
int GetRefCount()
{
return (*_pRefCount);
}
private:
int* _pRefCount;
char* _str;
};
//测试函数1:监视查看
//void Test()
//{
// String s1("xxxxxxxxxxxxxxxxx");
// String s2(s1);
// s2 = s1;
//
// String s3("yyyyyyyyyyyyy");
// String s4(s3);
//
// s1 = s3;
//}
//测试函数2:手动书写函数GetRefCount返回引用计数,断言方法判断是否一致
void Test()
{
String s1("xxxxxxxxxxxxxxxxx");
String s2(s1);
s2 = s1;
assert(s1.GetRefCount() == 2);
assert(s2.GetRefCount() == 2);
String s3("yyyyyyyyyyyyy");
String s4(s3);
s1 = s3;
assert(s1.GetRefCount() == 3);
assert(s2.GetRefCount() == 1);
assert(s3.GetRefCount() == 3);
assert(s4.GetRefCount() == 3);
}
int main()
{
Test();
system("pause");
return 0;
}
本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1745771