C++中string类的写时拷贝与读时拷贝

先附上我写的写时拷贝代码

class String
{
public:
	String(const char* s="")
		:_count(new int(1))
	{
		if (s == nullptr)
			s = "";
		_str = new char[strlen(s) + 1];
		strcpy(_str, s);
	}
	String(const String& s)
		:_count(s._count)
	{
		_str = s._str;
		++(*_count);
	}
	char& operator[](size_t index)//写时拷贝
	{
		if (_str == nullptr || index > strlen(_str))
		{
			static char nullchar = 0;
			return nullchar;
		}
		if (*_count == 1)
			return *(_str + index);
		char *str_t = new char[strlen(_str) + 1];
		strcpy(str_t, _str);
		_count = new int(1);
		_str = str_t;
		return *(_str + index);
	}
	String& operator=(const String& s)
	{
		if (--(*_count) == 0)
		{
			delete _count;
			delete _str;
		}
		_count = s._count;
		_str = s._str;
		++(*_count);
		return *this;
	}
	~String()
	{
		--(*_count);
		if (*_count == 0)
		{
			delete _count;
			delete _str;
		}
	}
private:
	char *_str;
	int *_count;
};

性能对比

在这里插入图片描述
第一个String类是写时拷贝类,可以明显看出性能的优势。
但是写时拷贝在读取时是有缺陷的,例如:

string original = "hello";
char & ref = original[0];
string clone = original;
ref = 'y';
  • 我们生成了一个string,并保留了它首字符的引用,然后复制这个string,修改string中的首字符。因为写操作只是直接的修改了内存中的指定位置,这个string就根本不能感知到有写发生,如果写时才拷贝是不成熟的,那么我们将同时会修改original和clone两个string。
  • 所以为了避免了你通过[]操作符获取string内部指针而直接修改字符串的内容,在你使用了[]后,这个字符串的写时才拷贝技术就失效了。
  • C++标准的确就是这样的,C++标准认为,当你通过迭代器或[]获取到string的内部地址的时候,string并不知道你将是要读还是要写。这是它无法确定,为此,当你获取到内部引用后,为了避免不能捕获你的写操作,它在此时废止了写时才拷贝技术!
  • 当然,string还提供了一些使迭代器和引用失效的方法。比如说push_back,等, 你在使用[]之后再使用迭代器之后,引用就有可能失效了。
发布了161 篇原创文章 · 获赞 52 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/qq_42837885/article/details/101454963
今日推荐