一:基本实现
#include "pch.h"
#include<iostream>
using namespace std;
#pragma warning(disable:4996)
class mystring
{
public:
mystring(const char *tmpstr = ""):pstr(new stringvalue(tmpstr))
{
cout<<"mystring构造函数执行了"<<endl;
}
mystring(const mystring& tmp):pstr(tmp.pstr)
{
++pstr->refcount;
cout << "mystring拷贝构造函数执行了" << endl;
}
mystring& operator=(mystring &tmp)
{
/*防止自己拷贝给自己*/
if (this == &tmp)
{
return *this;
}
/*拷贝赋值运算符=右边的对象引用计数减一*/
--pstr->refcount;
if (pstr->refcount == 0)
{
delete pstr;
}
/*拷贝赋值运算符=右边的对象指向新的对象
即:=左边的对象,然后引用计数加一,因为
又有了一个新的对象指向该内存块*/
pstr = tmp.pstr;
pstr->refcount++;
cout << "mystring拷贝赋值运算符执行了" << endl;
return *this;
}
~mystring()
{
--pstr->refcount;
if (pstr->refcount == 0)
{
delete pstr;
}
cout << "mystring析构函数执行了" << endl;
}
private:
struct stringvalue/*作为一个公共部分*/
{
char *str;
size_t refcount;
stringvalue(const char *tmpstr):refcount(1)
{
str = new char[strlen(tmpstr) + 1];
strcpy(str, tmpstr);
cout<<"stringvalue构造函数执行了"<<endl;
}
~stringvalue()
{
cout << "stringvalue析构函数执行了" << endl;
delete []str;
}
};
private:
stringvalue *pstr;
public:
size_t use_count()
{
return pstr->refcount;
}
};
int main(int argc, char **argv)
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF);//查看内存泄漏
mystring s1 = "I love China";
cout << s1.use_count() << endl;
mystring s2(s1);
cout << s1.use_count() << endl;
cout << s2.use_count() << endl;
mystring s3;
s3 = s1;
cout << s1.use_count() << endl;
cout << s3.use_count() << endl;
_CrtDumpMemoryLeaks();/*查看内存泄漏*/
return 0;
}
二:拓展
拓展一:
//针对一添加几个成员函数,由于标准库当中的string还有[]操作,这里也实现一下
const char& operator[](int index) const/*不可修改*/
{
cout << "const重载运算符[]执行了" << endl;
return pstr->str[index];
}
char& operator[](int index) /*可修改*/
{
cout << "非const重载运算符[]执行了" << endl;
if (pstr->refcount > 1)/*说明有多个对象指向同一个内存*/
{
--pstr->refcount;
pstr = new stringvalue(pstr->str);/*写时复制*/
}
return pstr->str[index];
}
//编译器对于调用const[]还是非const[]判断不出来,它不知道你使用[]时到底时用于读还是写,所以编译器比较简单粗暴,统一调用的是非const
mystring s3;
cout << s3[0] << endl;
s3[0] = 'y';
cout << s3[0] << endl;
拓展二:
由于跨线程使用的原因,要加锁,这里点一下。
内部加锁:一般不建议内部加锁
外部加锁:由程序员自己操作
拓展三:通过指针修改mystring所指向字符串的内容
在这里插入代码片