【String类浅拷贝的实现】C++:String类引用计数浅拷贝的两种实现

原创 2016年05月30日 17:17:36

第一种:

    只采用_str一个变量,利用强制转换前后偏移,获取存取计数的位置,以及存放字符串的位置。

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;

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

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

    //重载=
    String& operator= (const String& s)
    {
        if (s._str != _str)
        {    
            Release();
            _str = s._str;
        }
        return *this;
    }

    //重载[]
    char& operator[] (size_t index)
    {
        if (GetRefCount(_str) >1)
        {
            char* tmp = new char[strlen(_str) + 5];
            tmp += 4;
            GetRefCount(tmp) = 1;
            strcpy(tmp, _str);
            --(GetRefCount(_str));
            _str = tmp;

        }
        return _str[index];

    }

    ~String()
    {
        Release();
    }

void Release()
{
    if (*(int*)(_str) == 0)
    {
        delete[] (_str - 4);//指针返回首地址位置,释放整段空间
    }
}

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

private:
    char* _str;
};


void Test()
{
    String s1("xxxxxxxxxxxxxx");
    String s2(s1);
    s2 = s1;

    String s3("yyyyyyy");
    String s4(s3);
    s4 = s3;

    s3 = s1;

    s3[0] = 'S';
}
int main()
{
    Test();
    system("pause");
    return 0;
}


第二种:

    采用_str以及_pRefCount两个变量。

#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;


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)
    {
        /*if(_str != s.str)
        {
            if (--(*_pRefCount) == 0)
            {
                delete[] _str;
                delete _pRefCount;
            }
            _str = s._str;
            _pRefCount = s._pRefCount;
            ++(*_pRefCount);
        }
        return *this;*/

        if (_str != s._str)
        {
            if (--(*_pRefCount) == 0)
            {
                Release();
            }
            _str = s._str;
            _pRefCount = s._pRefCount;
            ++(*_pRefCount);
        }
        return *this;
    }

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

void Release()
{

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

//与测试函数2对应
int GetRefCount()
{
    return (*_pRefCount);
}

private:
    int* _pRefCount;
    char* _str;
};

//测试函数1:监视查看
//void Test()
//{
//    String s1("xxxxxxxxxxxxxxxxx");
//    String s2(s1);
//    s2 = s1;
//
//    String s3("yyyyyyyyyyyyy");
//    String s4(s3);
//
//    s1 = s3;
//}

//测试函数2:手动书写函数GetRefCount返回引用计数,断言方法判断是否一致
void Test()
{
    String s1("xxxxxxxxxxxxxxxxx");
    String s2(s1);
    s2 = s1;

    assert(s1.GetRefCount() == 2);
    assert(s2.GetRefCount() == 2);

    String s3("yyyyyyyyyyyyy");
    String s4(s3);

    s1 = s3;
    assert(s1.GetRefCount() == 3);
    assert(s2.GetRefCount() == 1);
    assert(s3.GetRefCount() == 3);
    assert(s4.GetRefCount() == 3);
}

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


本文出自 “Han Jing's Blog” 博客,请务必保留此出处http://10740184.blog.51cto.com/10730184/1745771

相关文章推荐

String类的浅拷贝、深拷贝、引用计数、写时拷贝

皆以s2=s1为例 浅拷贝:只是直接将s1的值拷贝过来,s1、s2共用同一块内存。 class String { public: String(const char* str) :_str(...
  • tttjp
  • tttjp
  • 2017年03月18日 18:55
  • 78

C++中String类模拟实现以及深拷贝浅拷贝

在C语言中/C++中,字符串是一个应用很广泛的类型,也是很基础的类型,C语言并没有直接处理字符串的操作而是采用字符指针和字符串数组进行操作,而在C++中标准库为我们封装了一个字符串的类供我们使用,使用...

c++ string类深拷贝其他版本(简洁版,引用计数版,写时拷贝版)

简洁版: class String { public: String(char* pStr="") { if(pStr==NULL) { _pStr...

string类的写时拷贝与引用计数

由于浅拷贝使多个对象共用一块内存地址,调用析构函数时导致一块内存被多次释放,导致程序奔溃。 实现string类的时候通常显示的定义拷贝构造函数和运算符重载函数。 由于释放内存空间,开辟内存空间时花...

String类引用计数的写时拷贝

写时拷贝: 当一个对象被拷贝构造多次,在不改变内容的情况下,多个对象共用同一个空间。 如果某个对象要改变内容,就要另外开辟一块相同的空间,然后改变这个对象的_str指针,再进行写操作 #...

C++浅拷贝、深拷贝及引用计数浅析

在C++开发中,经常遇到的一个问题就是与指针相关的内存管理问题,稍有不慎,就会造成内存泄露、内存破坏等严重的问题。不像Java一样,没有指针这个概念,所以也就不必担心与指针相关的一系列问题,但C++不...
  • iEearth
  • iEearth
  • 2015年10月22日 14:00
  • 1010

【C++】浅拷贝和深拷贝(String类)

浅拷贝 class String { public: String(const char *pStr = "") { if(NULL == pStr) { pstr = new ch...

string类浅拷贝优化2

如上个文章所事例,另外开辟一个指针的做法是不理想的。 用计数的方法平不是一定需要新的定义来实现。                我们在_pstr里面多开辟一块4个字节的空间就可以存储 一个i...

C++ 简易string类实现(三)-抽离引用计数

在C++ 简易string类实现(二)-引用计数里我们在String类实现里加入了引用计数,从而有效地实现了字符串的共享,降低内存消耗,提升了代码的执行效率.引用计数(RC)不仅可以用于字符串,任何c...

浅拷贝、深拷贝与引用计数

用模拟实现string来分析浅拷贝、深拷贝、引用计数。。。。。。。。
  • WRNGT
  • WRNGT
  • 2017年04月04日 16:04
  • 169
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【String类浅拷贝的实现】C++:String类引用计数浅拷贝的两种实现
举报原因:
原因补充:

(最多只允许输入30个字)