zangyuanan320的博客

Keep Dreaming!!

【C语言】【面试题】C++中String类引用计数器的浅拷贝写法与深拷贝写法

Linux操作下String类的实现--引用计数器

    1.引用计数器写法一

写法一个人比较喜欢叫他双指针法,因为他是在类里面创建了两个指针来实现的一个是指针_str,另外一个是用来保存指向同一块空间个数的指针_pRefCount.

class String
{
public:
    String(char* str = "")
        :_str(new char[strlen(str) + 1])
        , _pRefCount(new int(1))
    {
        strcpy(_str, str);
    }

    String(String& s)
        :_str(s._str)
        , _pRefCount(s._pRefCount)
    {
        ++(*_pRefCount);
    }

    String& operator=(const String& s)
    {
        /*char* tmp = new char[strlen(s._str) + 1];
        strcpy(tmp, s._str);
        delete[] _str;
        _str = tmp;*/ //这种写法不符合引用计数器的原理
        /*swap(_str, s._str);*/
        if (--(*_pRefCount) == 0)
        {
            delete[] _str;
            delete[] _pRefCount;
        }
        _str = s._str;
        _pRefCount = s._pRefCount;
        ++(*_pRefCount);
        return *this;
    }

    ~String()
    {
        if (--(*_pRefCount) == 0)
        {
            delete[] _str;
            delete[] _pRefCount;
        }
    }

private:
    char* _str;
    /*static int _refCount;*///变成静态的以后,需要在类的外面定义
    int* _pRefCount;
};

//int String::_refCount = 0;

void Test1()
{
    String s1("xxx");
    String s2(s1);
    String s3("yyy");
    s3 = s2;
    /*String s4(s3);*/
}

int main()
{
    Test1();
    system("pause");
    return 0;
}

这种写法简单易懂,也容易想到,但是由于要开辟两块空间一块大的一块小的,容易造成系统产生很多的内存碎片,所以有了另外一种写法

    2.引用计数器写法二

这种写法的思路是在开辟空间时多开辟四个字节的空间,在头部用四个字节的空间来保存指向同一块空间的个数,这样即避免了内存碎片的产生,也使得操作起来更为方便,不要要操作两块空间。

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

    String(String& s)
        :_str(s._str)
    {
        ++(*(int*)(_str - 4));
    }

    String& operator=(const String& s)
    {
        if (_str != s._str)
        {
            Release();
            _str = s._str;
            ++GetRefCount(_str);
        }
        return *this;
    }


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

    int& GetRefCount(char* str)
    {
        return *(int*)(str - 4);
    }

    void Release()
    {
        if (--GetRefCount(_str) == 0)
        {
            delete[](_str - 4);
        }
    }

private:
    char* _str;
};


int main()
{

    system("pause");
    return 0;
}


阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zangyuanan320/article/details/51538120
个人分类: C++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

【C语言】【面试题】C++中String类引用计数器的浅拷贝写法与深拷贝写法

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭