温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C++ String的实现

发布时间:2020-07-17 08:47:30 来源:网络 阅读:421 作者:nna_0914 栏目:编程语言

String的实现需要注意的是String的拷贝构造。它的拷贝构造有深拷贝和浅拷贝之分。

我们先来用浅拷贝实现String

class String
{
public:
	String()
	{
		str = new char('A');
	}
	String(char *s)
	{
		str = new char[strlen(s) + 1];
		if (str != NULL)
		{
			strcpy(str, s);
		}
	}
	String(const String& s)
	{
		str=s.str;
	}
	String& operator=(const String& s)
	{
		if (this != &s)
		{
		      str=s.str;
		}
		return *this;
	}

private:
	char *str;
};

void test()
{
	String s1("hello world");
	String s2(s1);
}

当s1,s2出自的作用域时,会自动调用析构函数,此时s1,s2指向同一片内存。所以这块内存会被释放两次,程序会崩溃。

C++ String的实现


所以在这里我们要采用深拷贝的方式


构造函数和赋值运算符重载

String(const String& s)
	{
		str = new char[strlen(s.str) + 1];    //new出来一块新的空间
		if (str)
		{
			strcpy(str, s.str);
		}
	}
	String& operator=(const String& s)
	{
		if (this != &s)
		{
			if (str != NULL)
			{
				delete[] str;
				str = new char[strlen(s.str) + 1];
				strcpy(str, s.str);
			}
		}
		return *this;
	}

C++ String的实现

还有一种方法可以解决这个一块空间会被多次释放的问题,那就是写时拷贝

在第一次构造一个对象的时候,多开辟四个字节当做计数器,用来记录有几个指针指向这块空间。每当用这块空间拷贝构造一个新对象或者把这块空间赋给另外一个对象时,计数器相应增加。那么当调用析构函数时,每次计数器减一,当计数器减到一时,说明只有一个指针指向这块空间,此时再把这块空间delete,就不会出现一块空间多次释放的问题了。

class String
{
public:
	String(char *str="")
		:_str(new char[strlen(str)+1+4])
	{
		*((int *)_str) = 1;         //将开辟的空间前4个字节强制转换成整型并赋为1
		_str = _str + 4;       //将_str重新定为真正字符串开始的地方,这样比较方便
		strcpy(_str, str);     //不用每次向后找
	}
	String(const String& str)
	{
		_str = str._str;
		(*((int *)(_str - 4)))++;    
	}
	~String()
	{
		if (*_str != NULL)    
		{
			if (((*((int *)(_str - 4)))--) == 0)    //判断计数器是否减到0
			{
				delete[] (_str-4);
			}
		}
	}
public:
	String& operator=(const String& str)
	{
		if (this != &str)
		{
			if (((*((int *)(_str - 4)))--) == 0)
			{
				delete[] (_str-4);
			}
			_str = str._str;
			(*(int *)(str._str - 4))++;
			return *this;
		}
	}
	char& operator[](int index)
	{
		char *tmp = _str;
		if (((*(int *)(_str - 4))-1) != 0)
		{
			(*(int *)(_str - 4))--;
			_str = new char[strlen(_str) + 5];
			(*(int *)(_str + 4)) = 1;
			_str = _str - 4;
			strcpy(_str, tmp);
		}
		return _str[index];
	}
private:
	char *_str;
};

C++ String的实现

但是这样做也有一个坏处。就是指向同一块空间的指针,只要改一个指针指向的内容,等于其他的指针指向的内容也跟着改变了。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI