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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
}


以上是关于C语言面试题C++中String类引用计数器的浅拷贝写法与深拷贝写法的主要内容,如果未能解决你的问题,请参考以下文章

c++ 实现引用计数类的目的,原理及源码

C++类的浅拷贝深拷贝以及写时拷贝问题

使用引用计数和copy-on_write实现String类

C++面试题

一C++基础面试题

js运用递归实现浅拷和深拷贝