C++:String中的写时拷贝
定义
写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。
引用计数
引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象时资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源。
模拟实现写时拷贝
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<list>
#include<assert.h>
#include<vld.h>
using namespace std;
namespace bit
{
//浅拷贝
class string
{
friend ostream& operator<<(ostream &out, const string &s);
public:
string(const char *str = "") :m_use_count(new int(1))
{
if (nullptr == str)
m_data = new char[1]{ '\0' };
else
{
m_data = new char[strlen(str) + 1];
strcpy(m_data, str);
}
}
string(const string &s) :m_data(s.m_data), m_use_count(s.m_use_count)
{
//增加引用计数
increment_ref_count();
}
string& operator=(const string &s)
{
if (this != &s)
{
decrement_ref_count();
m_data = s.m_data;
m_use_count = s.m_use_count;
increment_ref_count();
}
return *this;
}
~string()
{
decrement_ref_count();
}
public:
void increment_ref_count()
{
(*m_use_count)++;
}
void decrement_ref_count()
{
if (--(*m_use_count) == 0)
{
//释放数据空间
delete[]m_data;
m_data = nullptr;
//释放引用计数空间
delete m_use_count;
m_use_count = nullptr;
}
}
public:
//写时拷贝
void to_upper()//小写字母转换为大写字母
{
char *new_data = new char[strlen(m_data) + 1];
strcpy(new_data, m_data);
int *new_use_count = new int(1);
char *pstr = new_data;
while (*pstr != '\0')
{
*pstr -= 32;
pstr++;
}
decrement_ref_count();
m_data = new_data;
m_use_count = new_use_count;
}
private:
char *m_data;
//引用计数
int *m_use_count;
};
ostream& operator<<(ostream &out, const string &s)
{
out << s.m_data;
return out;
}
};
void main()
{
bit::string str("abc"); //独立
bit::string str1 = str;
cout << "str = " << str << endl;
cout << "str1 = " << str1 << endl;
str.to_upper();
cout << "str = " << str << endl;
cout << "str1 = " << str1 << endl;
system("pause");
}
测试用例