模拟实现string——写时拷贝

本文介绍了写时拷贝机制的基本原理及应用,通过具体代码示例解释了如何使用引用计数来优化字符串对象的复制过程,减少内存开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模拟实现string——深浅拷贝
上篇文章谈到了浅拷贝的缺陷,我们可以用深拷贝和写时拷贝改善
深拷贝其实也是有缺陷的——每次的开辟空间消耗太大
下面我们来介绍一下写时拷贝
引用计数的写时拷贝是基于引用计数的浅拷贝

那么什么是写时拷贝:其实写时拷贝的意思就是: 当你读取到这个空间的时候,并不会开辟出一个一模一样的空间出来给你,当你真正需要拷贝的时候,那么他就会开辟出空间给你。
当我们要对它进行写操作是才会真正的拷贝一块内存大小

它的大致原理为
江湖倦客
我们引用了引用计数,每次当引用计数变为一时才会释放
具体的代码如下:

class String
{
public:
    String(const char* str)
        :_str(new char[strlen(str) + 1])
        , _refCount(new int(1))
    {
        strcpy(_str, str);
    }
    String(String &s)
    {
        _str = s._str;
        _refCount = s._refCount;
        (*_refCount)++;
    }
    void Relese()
    {
        if (--(*_refCount) == 0)
        {
            delete[] _str;
            delete[] _refCount;
        }
    }
    String &operator=(const String &s)
    {
        if (_str != s._str)
        {
            Relese();
            _str = s._str;
            _refCount = s._refCount;
            (*_refCount)++;
        }
        return *this;
    }
    char &operator[](size_t pos)
    {
        CopyOnWrite();
        return _str[pos];
    }
    void CopyOnWrite()
    {
        if (*_refCount > 1)
        {
            char *tmp = new char[strlen(_str) + 1];
            strcpy(tmp, _str);
            --(*_refCount);
            _str = tmp;
            _refCount = new int(1);

        }
    }
    ~String()
    {
        Relese();
    }

private:
    char*_str;
    int*_refCount;

};

我们可以发现这样就可以少开辟很多空间

但是在这个程序上面refCount占用了一个空间,指向的内容占用了一个空间,我们可以对这个程序进行优化

我们可以开辟一个空间让这块空间的前四个字节存放refCount,后面存放指向的内容
67
每次释放的时候我们只释放引用计数后面的内容
代码如下:

#include<iostream>
#include<windows.h>
using namespace std;

class String
{
public:
    String(const char* str = "")
        :_str(new char[strlen(str) + 5])
    {
        GetRefCount() = 1;
        _str += 4;
        strcpy(_str, str);
    }
    String(String &s)
        :_str(s._str)
    {

        GetRefCount()++;
    }

    String &operator=(const String &s)
    {
        if (_str != s._str)
        {
            if (--GetRefCount() == 0)
            {
                delete[](_str - 4);
            }
            _str = s._str;
            GetRefCount()++;
        }
        return *this;
    }

    char& operator[](size_t index)
    {
        if (GetRefCount() == 1)                   //如果计数器为1,则直接返回    
        {
            return _str[index];
        }
        GetRefCount()--;
        char *tmp = _str;
        _str = new char[strlen(tmp) + 1 + 4];
        _str += 4;
        strcpy(_str, tmp);
        GetRefCount() = 1;
        return _str[index];
    }
    int &GetRefCount()
    {
        return(*(int*)(_str - 4));
    }

    ~String()
    {
        if (--GetRefCount() == 0)
        {
            delete[](_str - 4);
        }
    }

private:
    char*_str;


};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值