引用计数器 写实拷贝
class String;
class String_rep//引用计数类
{
friend class String;
friend ostream& operator<<(ostream &out, const String &s);
public:
String_rep(const char *str = ""):use_count(0)
{
m_data = new char[strlen(str)+1];
assert(m_data != NULL);
strcpy(m_data, str);
}
String_rep(const String_rep &rep);
String_rep& operator=(const String_rep &rep);
~String_rep()
{
delete []m_data;
m_data = NULL;
}
public:
int get_use_count()const
{
return use_count;
}
void increment()
{
++use_count;
}
void decrement()
{
if(--use_count == 0)
{
delete this; //自杀式 先调用析构函数释放m_data数据空间再释放对象(自己)空间
}
}
private:
char *m_data;
int use_count;
};
class String
{
friend ostream& operator<<(ostream &out, const String &s);
public:
String(const char *str = "")
{
rep = new String_rep(str);//new申请空间,调用String_rep的构造函数给数据空间进行初始化。体现了new和malloc、calloc的区别。
rep->increment();//计数
}
String(const String &s)
{
rep = s.rep;//浅拷贝
rep->increment();//计数
}
String& operator=(const String &s)
{
if(this != &s)
{
rep->decrement();//先修改之前指向空间的计数
rep = s.rep;//修改指向
rep->increment();//修改当前指向空间的计数
}
return *this;
}
~String()
{
rep->decrement();
}
public:
//写时拷贝 难点
void to_upper()
{
if(rep->get_use_count() > 1)//是否重新开辟空间
{
String_rep *new_rep = new String_rep(rep->m_data);
rep->decrement();
rep = new_rep;
rep->increment();
}
char *ch = rep->m_data;
while(*ch != '\0')//注意ch是指针,*ch取值
{
if(*ch>='a' && *ch<='z')
*ch -= 32;
ch++;//ch指向偏移一位
}
}
private:
String_rep *rep;
};
ostream& operator<<(ostream &out, const String &s)
{
out<<s.rep->m_data;
return out;
}
void main()
{
String s1("abc");//创见对象并初始化
cout<<"s1 = "<<s1<<endl;
String s2 = s1;//拷贝构造
cout<<"s2 = "<<s2<<endl;
s1.to_upper();//字母转换
cout<<"s1 = "<<s1<<endl;
cout<<"s2 = "<<s2<<endl;
}