您的位置:首页 > 编程语言 > C语言/C++

【String类浅拷贝的实现】C++:String类引用计数浅拷贝的两种实现

2016-02-28 15:30 597 查看
第一种:
只采用_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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息