String类简单实现

浅拷贝:也称位拷贝,编译器只是直接将指针的值拷贝过来,结果多个对象共用同一块内存,当一个对象将这块内存释放掉之后,另一些对象不知道该块空间已经还给了系统,以为还有效,所以在对这段内存进行操作的时候,发生了访问违规。

深拷贝:为避免浅拷贝的问题,存在内存拷贝时开辟一块和被拷贝对象一样大小的空间并将其内存中的数据也拷贝到新开辟的内存中

一、普通深拷贝

#include <iostream>
using namespace std;
class String
{
public:

    String(char* ptr = ""):             //构造函数
    _pStr(new char[strlen(ptr) + 1])
    {
            strcpy(_pStr, ptr);
    }
    String(const String& s):  //拷贝构造
        _pStr(new char[strlen(s._pStr) + 1])
    {
        strcpy(_pStr, s._pStr);
    }
    String& operator= (const String& s)//赋值运算符重载
    {
        if (this != &s)
        {
            if(_pStr)
                delete[] _pStr;
            _pStr = new char[strlen(s._pStr) + 1];
            strcpy(_pStr, s._pStr);
        }
        return *this;
    }
    ~String()
    {
        if (_pStr)
        {
            delete[] _pStr;
            _pStr = NULL;
        } 
    }

private:
    char* _pStr;

};
int main()
{
    String s;
    String s1("hello");
    String s2(s1);
    s = s2;
    system("pause");
    return 0;
}

二、简单深拷贝


#include <iostream>
using namespace std;
class String
{
public:
    String(char* ptr = "") :                     //构造函数
        _pStr(new char[strlen(ptr) + 1])
    {
        strcpy(_pStr, ptr);
    }
    String(const String& s) :                  //拷贝构造
        _pStr(NULL)
    {
        String temp(s._pStr);
        swap(temp._pStr, _pStr);
    }
    String& operator=(const String& s)       //赋值运算符重载
    {
        if (this != &s)
        {
            String temp(s);
            swap(temp._pStr, _pStr);
        }
        return *this;
    }
    ~String()                                 //析构函数
    {
        if (_pStr)
        {
            delete[] _pStr;
        }
    }
    size_t Size()const                           // 获取大小
    {

        return (Lengh()*sizeof(char) + 1);
    }
    size_t Lengh()const                  //获取长度
    {
        size_t length = 0;
        char* p = _pStr;
        while (*p++)
        {
            length++;
        }
        return length;
    }
    char& operator[](size_t index)     //随机访问
    {
        return *(_pStr + index);

    }
    const char& operator[](size_t index)const    
    {
        return *(_pStr + index);
    }
    bool operator>(const String& s)    //大于运算符重载
    {
        char* s1 = _pStr;
        char* s2 = s._pStr;
        while (*s1 == *s2 && *s2)
        {
            ++s1;
            ++s2;
        }
        if ((*s1 - *s2) > 0)
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }
    bool operator<(const String& s)           //小于运算符重载
    {
        if (*this > s)
        {
            return 0;
        }
        else
        {
            return 1;
        }

    }
    bool operator==(const String& s)   //等于运算符重载
    {
        char* s1 = _pStr;
        char* s2 = s._pStr;
        while (*s1 == *s2 && *s2)
        {
            ++s1;
            ++s2;
        }
        if ((*s1 - *s2) == 0)
        {
            return 1;
        }
        else
        {
            return 0;
        }

    }
    bool operator!=(const String& s)    //不等于运算符重载
    {
        if (*this == s)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    void Copy(const String& s)    //拷贝函数
    {
        char* dest = _pStr;
        char* src = s._pStr;
        if (s.Lengh() < Lengh())
        {
            while (*dest++ = *src++)
            {
                ;
            }
        }
        else
        {
            delete[] _pStr;
            _pStr = new char[s.Lengh() + 1];
            while (*dest++ = *src++)
            {
                ;
            }
        }

    }
    bool strstr(const String& s)    //找子串
    {
        char* dest = _pStr;
        char* src = s._pStr;
        char* cur = _pStr;
        while (*cur++)
        {
            dest = cur;
            src = s._pStr;
            while (*dest == *src && *src)
            {
                ++src;
                ++dest;
            }
            if (  *src == '\0' )
            {
                return 1;
            } 
        }
        return 0;
    }
    String& operator+=(const String& s)  //+=符号重载
    {

        char* temp =  new char[Lengh() + s.Lengh() + 1];
        strcpy(temp, _pStr);
        delete[] _pStr;
        _pStr = temp;
        char* dest = _pStr;
        char* src = s._pStr;
        while (*dest)
        {
            ++dest;
        }
        while (*dest++ = *src++)
        {
            ;
        }
        return *this;
    }
private:
    char* _pStr;
};
int main()
{
    String s("helloworld");
    String s1("hello");
    String s2(s1);
    String s3("world");
    size_t a = s1.Size();
    size_t b = s1.Lengh();
    s1 += s3;
    s2.Copy(s1);
    bool x = (s == s1);
    system("pause");
    return 0;
}

三、引用计数 (多开辟一块空间,用来存放对象使用同一块空间的个数)

#include <iostream>
#include <assert.h>
using namespace std;
class String
{
public:
    String(char* ptr = "") :
        _pStr(new char[strlen(ptr) + 1 + 4])  //多开辟4个字节

    {
        _pStr += 4;     
        strcpy(_pStr, ptr);
        Count() = 1;
    }
    String(const String& s):
        _pStr(s._pStr)
    {
        Count()++;
    }
    String& operator=(const String& s)
    {
        if (this != &s)
        {
            Release();
            _pStr = s._pStr;
            Count()++;
        }
        return *this;
    }
    ~String()
    {

        if (_pStr && (0 == --Count()))
        {
            delete[] (_pStr - 4);

        }

    }
    char& operator[](size_t num)
    {
        assert( num < strlen(_pStr));
        return *(_pStr + num);
    }

private:
    void Release()
    {
        if (0 == --Count())
        {
            delete[] (_pStr - 4);
        }
    }
    int&  Count()                     
    {
        _count = (int *)(_pStr - 4);
        return (*_count);
    }
    char* _pStr;
    int*  _count;                        //计数
};

int main()
{
    String s;
    String s1("hello");
    String s2(s1);
    String s3(s);
    s = s2;
    s1[0] = 'a';
    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值