string类的写时拷贝

如图所示,str1和str2指向的内存中内容是一样的,如果系统浅拷贝的话,一个释放后,另一个释放时找不到要是放的内存;如果自己实现深拷贝,会出现内存浪费。所以实现string类的写时拷贝。
这里写图片描述
引用计数放在什么地方合适呢?
1、放在类中
作为普通成员变量,那么每个对象中都有一个count,不能实现共用;
作为静态成员变量,定义str1和str2后,count=2,那么再定义string str3(“world”);后,count又会等于1。
也就是说,放在类中不能实现。
2、放在内存中
这里写图片描述
如果出现str1[1] = ‘s’;这样的情况呢?
这个时候会修改str1的内容,那么就需要实现深拷贝,所以在operator[]中实现深拷贝。

#include<iostream>
using namespace std;
#pragma warning(disable:4996);
class String
{
public:
    String(char* ptr = NULL)
        :mptr(new char[strlen(ptr) + 5])//加上'\0'和引用计数的长度
    {
        mptr += 4;//找到存放数据的位置
        strcpy(mptr, ptr);
        getRefCount(mptr) = 1;
    }
    String(const String& rhs)
        :mptr(rhs.mptr)
    {
        ++getRefCount(mptr);
    }
    String& operator=(const String& rhs)
    {
        if (this != &rhs)
        {
            Release();
            mptr = rhs.mptr;
            ++getRefCount(mptr);
        }
        return *this;
    }
    char& operator[](int index)
    {
        if (getRefCount(mptr) > 1)//如果只有一个指针指向的话,直接修改就可以
        {
            char* ptr = mptr;
            --getRefCount(ptr);
            mptr = new char[strlen(ptr) + 5];
            mptr += 4;
            getRefCount(mptr) = 1;
            strcpy(mptr, ptr);
        }
        return mptr[index];
    }
    ~String()
    {
        Release();
    }
private:
    void Release()
    {
        if (--getRefCount(mptr) == 0)
        {
            delete[] (mptr - 4);
        }
    }
    int& getRefCount(char* ptr)
    {
        return *(int*)(ptr - 4);
    }
    char* mptr;
};
int main()
{
    String str1("hello");
    String str2(str1);

    String str3("world");
    str3 = str1;
    str1[0] = 's';
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值