string类精简版

Posted TangguTae

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了string类精简版相关的知识,希望对你有一定的参考价值。

1、传统写法

要实现一个很简单的string类首先得有一个char* 的成员变量

然后构造函数、析构函数、拷贝构造函数、赋值函数缺一不可,拷贝构造函数和赋值函数如果不写,编译器会自动生成,然而编译器自动生成的这两会存在一个很大的问题:浅拷贝

编译器自动生成的拷贝构造函数都是逐字节拷贝的,当进行析构时,会对同一个地址释放两次,造成程序崩溃。

给出如下代码

class string_t

private:
	char* _str;//成员变量
public:
	string_t(const char* str = "")//构造函数
		:_str(new char[strlen(str) + 1])
	
		strcpy(_str, str);
	
	~string_t()//析构函数
	
		delete[] _str;
		_str = nullptr;
	
	string_t(const string_t& s)//拷贝构造
		:_str(new char[strlen(s._str) + 1])
	
		strcpy(_str, s._str);
	
	string_t& operator=(const string_t& s)//赋值
	
		if (this != &s)
		
			delete[] _str;
			_str = new char[strlen(s._str) + 1];
			strcpy(_str, s._str);
		
		return *this;
	
;

2、现代写法

class string_m

private:
	char* _str;
public:
	string_m(const char* str = "")
		:_str(new char[strlen(str) + 1])
	
		strcpy(_str, str);
	
	~string_m()
	
		delete[] _str;
		_str = nullptr;
	
	string_m(const string_m& s)//下面两个比较巧妙
		:_str(nullptr)
	
		string_m tmp(s._str);
		std::swap(_str, tmp._str);
	
	string_m& operator=(string_m s)//很巧妙
	
		std::swap(_str, s._str);
		return *this;
	
;

这里的现代写法利用临时变量的生命周期,出了函数作用域会自动调用析构函数释放资源

对于拷贝构造,定义一个临时变量,将两个字符串的地址空间互换,生命周期结束后,原来的地址会被释放掉,这样就拷贝构造出来了一个对象。这里需要注意一下需要先让_str为空,因为初始化为随机值,随便释放未知空间存在风险。

对于operator =,则更为巧妙,这里不用传引用,而是传对象的拷贝,这个也属于临时对象,交换二者空间,临时对象同样会被析构掉,整体代码很简洁。

以上是关于string类精简版的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis精简版--实现接口代理方式实现Mapper(Dao) 和动态SQL

MyBatis精简版--实现接口代理方式实现Mapper(Dao) 和动态SQL

带你深入了解string类接口(传统写法实现string类)

C++初阶:string类string类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现

C++初阶:STL —— stringstring类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现

C++初阶:STL —— stringstring类 | 浅拷贝和深拷贝(传统写法和现代写法) | string类的模拟实现