当前位置: 首页 > news >正文

string的实现(下)

1.面试中的简单实现

在面试中,由于时间的缘故,我们只需要简单实现string就行,其中就包括构造函数,析构函数,拷贝构造,赋值运算即可。由于不涉及容量的改变,只需要一个成员变量_str即可。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;class my_string
{
public:my_string(const char* s = ""):_str(new char[strlen(s)+1]){strcpy(_str, s);}//构造函数my_string(const my_string& s):_str(nullptr){my_string s1(s.c_str());swap(_str, s1._str); //交换首地址元素,结束旧元素的s1,会自动调用析构函数析构,一定要置原_str为空,不然就会析构错误}//拷贝构造函数~my_string(){delete[] _str;_str = nullptr;}//析构函数my_string& operator=(const my_string& s){my_string s1(s);swap(_str, s1._str);return *this;}const char* c_str()const{return _str;}
private:char* _str;
};

2.复杂功能的实现

注意,其中可能掺杂了strcpy的来交换_str的传统写法,我们更倾向于在实现的时候调用库函数swap。

#define  _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;class my_string
{friend istream& operator>>(istream& ci, my_string& s);
public:my_string(const char* s=""){_size = _capacity = strlen(s);_str = new char[_size + 1];strcpy(_str, s);}//实现了默认和带参构造//my_string(const my_string& s)//{//	_size = _capacity = strlen(s._str);//	_str = new char[_size + 1];//	strcpy(_str, s._str);//}//实现拷贝构造//拷贝构造的现代写法(使用swap)my_string(const my_string& s):_str(nullptr) //如果初始化 换给s中的str后,s析构delete时就会出问题{my_string tmps(s._str);swap(tmps);}~my_string(){delete[] _str;_capacity = _size = 0;_str = nullptr;}char& operator[](size_t pos)const{assert(pos >= 0 && pos < _size);return *(_str + pos);}typedef char* iterator;char* begin()const{return _str;}char* end()const{return _str + _size ;}void push_back(char c){if (_capacity == _size){size_t capacity = _capacity == 0 ? 4 : 2 * _capacity;reserve(capacity);}_str[_size++] = c;_str[_size] = '\0';}void append(const char* s){size_t len = strlen(s);if (_size + len > _capacity){size_t capacity =  _size + len;reserve(capacity);}strcpy(_str + _size, s);_size = _size + len;}void operator+=(char c){push_back(c);}void operator+=(const char* str){append(str);}void reserve(size_t n){if (n > _capacity){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void resize(size_t n,char c = '\0'){if (n <= _size){_str[n] = '\0';}else{reserve(n);for (size_t i = _size; i < n; i++){_str[i] = c;}_str[n] = '\0';}}my_string& insert(size_t pos, size_t n, char c){assert(pos <= _size);if (_capacity < _size + n){reserve(_size + n);}//先增容int end = _size;while (end >= (int)pos){_str[end + n] = _str[end];end--;}//将pos位置后的移动,腾出n个位置while (n){_str[pos] = c;pos++;n--;}return *this;}my_string& insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (_capacity < _size + len){reserve(_size + len);}//扩容int end = _size;while (end >= (int)pos){_str[end + len] = _str[end];end--;}//腾位置strncpy(_str + pos, str, len);return *this;}my_string erase(size_t pos, size_t len = npos){assert(pos < _size);if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{for (size_t i = pos + len; i <= _size; i++){_str[i - len] = _str[i];}}return *this;}size_t find(char c, size_t pos = 0)const{assert(pos < _size);for (size_t i = pos; i < _size; i++){if (_str[i] == c){return i;}}return npos;}size_t find(const char* str, size_t pos = 0)const{assert(pos < _size);const char* s = strstr(_str + pos, str);if (s){return s - begin();}return npos;}//my_string& operator=(const my_string& s)//{//	delete[] _str;//	char* tmp = new char[strlen(s._str) + 1];//	strcpy(tmp, s._str);//	_str = tmp;//	return *this;//}// operator=的现代写法(使用swap)///*my_string & operator=(const my_string & s)//{//	my_string s1(s);//	swap(s1);//}*/my_string& operator=(my_string s){swap(s);return *this;}bool operator==(const my_string& s)const{int c = strcmp(_str, s._str);return c == 0;}bool operator> (const my_string& s)const{int c = strcmp(_str, s._str);return c > 0;}bool operator< (const my_string& s)const{int c = strcmp(_str, s._str);return c < 0;}bool operator>=(const my_string& s)const{return !(*this < s);}bool operator<=(const my_string& s)const{return !(*this > s);}size_t size()const{return _size;}size_t capacity()const{return _capacity;}char* c_str() const{return _str;}void swap(my_string& s){::swap(_str, s._str); //_str指向的是地址,所以库的swap实现了首元素地址交换,就交换了整个::swap(_size, s._size);::swap(_capacity, s._capacity);}
private:char* _str;size_t _size;//已经有多少有效字符size_t _capacity;//能存储多少有效字符static size_t npos;
};size_t my_string::npos = -1;ostream& operator<<(ostream& cou, const my_string& s)
{cout << s.c_str();return cou;
}
istream& operator>>(istream& ci, my_string& s)
{while (1){char c;c=ci.get();if (c == '\0' || c == '\n'){break;}else{s.push_back(c);}}return ci;}//利用istream中的get获取单个字符


http://www.mrgr.cn/news/41718.html

相关文章:

  • 生信初学者教程(二十三):REF+SVM筛选候选标记物
  • 大语言模型入门(三)——提示词编写注意事项
  • MYSQL 乐观锁
  • 路由交换实验指南
  • [产品管理-41]:什么是变量、属性、特征、特性?他们的相同点、不同点?
  • C++ 语言特性10 - 委托构造函数
  • 开放式耳机哪个品牌好?分享几款不错的开放式蓝牙耳机
  • C++常引用详解
  • Java开发类加载器实现机制
  • Visual Studio 使用技巧之界面布局
  • 浏览器 F12 application 应用程序面板
  • 10. 模块
  • 大学城就餐推荐系统小程序的设计
  • 深入理解 Git 一个开发者的必备工具
  • 【2023工业3D异常检测文献】Shape-Guided: 基于形状引导和双记忆库的异常检测方法
  • 使用rust写一个Web服务器——async-std版本
  • vue3 + ts + cesium:绘制自由曲线(polyline)
  • 性能测试的方式有哪些
  • C++ 双端队列(deque)的深入理解
  • 【SpringBoot】