C++ String类的模拟实现

关于String类的模拟实现:
一.深拷贝:

1.传统写法:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string>
#include <assert.h>
using namespace std;
class String
{
public:
	//构造函数
	String(const char* str = "")
	{
		if (str == nullptr)
		{
			assert(false);
			return;
		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	//析构函数
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
	//赋值运算符重载
	String& operator=(const String& s)
	{
		if (&s != this)
		{
			delete[] this->_str;
 
			_str = new char[strlen(s._str) + 1];
			strcpy(_str, s._str);
		}
        //防止连续赋值
		return *this;
	}
 
	//拷贝构造
	String(const String& s)
		:_str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}
private:
	char* _str;
};

2.现代写法:

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string>
#include <assert.h>
using namespace std;
class String
{
public:
	String(const char* str = "")
	{
		if (nullptr == str)
			str = "";
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
 
	String(const MyString& s)
	{
		MyString str(s._str);
		swap(_str, str._str);
	}
 
	String& operator=(MyString& s)
	{
		swap(_str, s._str);
		return *this;
	}
	~String()
	{
		if (_str)
		{
			delete[] _str;
			_str = nullptr;
		}
	}
 
private:
	char* _str;

};

二.引用计数:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string>
#include <assert.h>
using namespace std;
class String{
public:
    //构造函数
    String(const char* ptr = "")
        :_count(new int[0])
        , _ptr(new char[strlen(ptr)+1])
    {
        if (ptr == NULL)
        {
            _ptr = new char[1];
            *_ptr = '\0';
        }
        else
            strcpy(_ptr, ptr);

        *_count = 1;
    }
    //拷贝构造函数
    String(const string& s)
        :_count(s._count)
    {
        _ptr = (char*)(s._ptr);
        _count = s._count;
        (*_count)++;
    }

    String& operator=(const string& s)
    {
        if (_ptr!=s._ptr)
        {
            _ptr = s._ptr;
            _count = s._count;
            (*_count)++;
        }
        return *this;
    }
    ~String()
    {
        if (_ptr == NULL)
            return;
        else
        {
            if (--(*_count)==0)
            {
                delete[] _ptr;
                delete[] _count;
                _ptr = NULL;
                _count = NULL;
            }
        }
    }
private:
    char* _ptr;
    int* _count;
};


三.写时拷贝:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <string>
#include <assert.h>
using namespace std;
class string
{
public:
    string(const char* ptr="")
        :_ptr(new char[strlen(ptr)+4+1])//每次多创建4个空间来存放当前地址有几个对象
    {
        if (_ptr == NULL)
        {
            (*(int*)_ptr) = 1;//前四个字节拿来计数
            _ptr += 4;
            *_ptr = '\0';
        }
        else
        {
            (*(int*)_ptr) = 1;
            _ptr += 4;
            strcpy(_ptr, ptr);
        }
    }

    string(const string& s)
        :_ptr(s._ptr)
    {
        ++(*(int*)(_ptr - 4));//向前偏移4个字节将计数加1
    }
    string& operator=(const string& s)
    {
        if (_ptr != s._ptr)
        {
            if (--(*(int*)(_ptr-4)) == 0)
            {
                delete[] _ptr;
                _ptr = NULL;
            }
            _ptr = s._ptr;
            ++(*(int*)(_ptr - 4));
        }
    }

    ~string()
    {
        if (_ptr == NULL)
        {
            return;
        }
        else
        {
            if (--(*(int*)(_ptr - 4)) == 0)
            {
                delete[] (_ptr-4);
                _ptr = NULL;
            }
        }
    }

    char& operator[](size_t index)//下标访问操作符重载
    {
        assert(index >= 0 && index < strlen(_ptr));
        if ((*(int*)(_ptr - 4))>1)//多个对象指向同一块空间
        {
            char* tmp = new char[strlen(_ptr) + 4 + 1];//新开辟一块空间
            tmp += 4;//向后偏移4
            strcpy(tmp,_ptr);
            --(*(int*)(_ptr - 4));//将原来空间的计数器减1

            _ptr = tmp;//将当前对象指向临时空间
            *((int*)(_ptr - 4)) = 1;//将新空间的计数器变为1
        }
        return _ptr[index];
    }
private:
    char* _ptr;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值