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类的模拟实现