【C++

编程入门 行业动态 更新时间:2024-10-14 20:23:20

【C++

【C++

一、基本思路

新建一个项目,在项目中创建头文件string.h 源文件string.cpp

在头文件中,先定义一个新的命名空间(为了防止与库中的string发生冲突),命名空间的名字可以按照自己意愿来命名。

接下来就可以在命名空间中来模拟实现string类辣

在实现的过程中可以多查查string::operator+= - C++ Reference (cplusplus)

了解函数功能,然后再去实现 

【1】确定成员变量: size_t _size; size_t _capacity; char* _str;

【2】成员函数模拟实现

(1)构造和析构函数

		string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_size + 1];my_strcpy(_str, str);//完成初始化工作}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;std::cout << "~string()" << std::endl;}

(2)size()和capacity()

		size_t size()const{return _size;}size_t capacity()const{return _capacity;}

(3)operator[ ]重载

		char& operator[](size_t pos){assert(pos <= _size);return _str[pos];}

(4)reserve()

		void reserve(size_t n = 0){char* tmp = new char[n];//在堆区开辟空间,出函数不会销毁my_strcpy(tmp, _str);//由于有的vs使用strcpy会报错,所以可以用自己实现的strcpydelete[] _str;_str = tmp;_capacity = n;}

(5)push_back()

		void push_back(char c){if (_size == _capacity){reserve(_capacity == 0 ? 6 : _capacity * 2);}_str[_size] = c;_size++;_str[_size] = '\0';}

(6)operator+=的实现

		string& operator+= (char c){push_back(c);return *this;}string& operator+= (const char* s){size_t len = strlen(s);if (_size + len > _capacity){reserve(_size + len+10);}append(s);return *this;}

(7)append()

		string& append(const char* s){size_t len = strlen(s);if (_size + len > _capacity){reserve(_size + len + 10);}my_strcpy(_str + _size, s);return *this;}

(8)c_str()

		const char* c_str()const{return _str;}

(9)operator<<

这个函数得在类外实现,因为在类内实现的话,默认第一个参数是this,那么在实际使用的时候对象名就得写在ostream的左边,与我们常规写法不一样。

由于库中的_str是私有成员,因此可以通过调用函数c_str来获取_str

std::ostream& operator<<(std::ostream& os, const abl::string& str)
{os << str.c_str() ;return os;
}

(10)拷贝构造

		//现代写法string(const string& s):_str(nullptr),_size(0),_capacity(0){string tmp(s._str);//调用默认构造函数string(const char* str = "")swap(tmp);//this可能没有初始化,析构的时候就会报错,因此要写参数初始化列表}//string(const string& s)//{//	_str = new char[s._capacity + 1];//	memcpy(_str, s._str, s._size);//	_size = s._size;//	_capacity = s._capacity;//}

(11)insert

		string& insert(size_t pos, size_t n, char c){assert(pos <= _size);if (_size + n > _capacity){reserve(_size + n);}size_t end = _size+n;for (; end>=pos+n; end--){//abcd  size==4   pp  n==2  end==6  end-n==4_str[end] = _str[end-n];}for (size_t i = 0; i < n; i++){_str[pos + i] = c;}_size += n;return *this;}string& insert(size_t pos, const char* s, size_t n){assert(pos <= _size);size_t len = strlen(s);if (_size + n > _capacity){reserve(_size + n);}size_t end = _size + n;for (; end >= pos + n; end--)//当pos==0时,end>=pos恒成立,因为end为size_t类型,不可能是负数{//abcd  size==4   pp  n==2  end==6  end-n==4_str[end] = _str[end - n];}for (size_t i = 0; i < n; i++){_str[pos + i] = s[i];}_size += n;return *this;}

二、完整代码

1、string.h
#pragma once
#include <assert.h>
#include <cstring>
#include <iostream>
#include <stdio.h>
//#include<string.h>
void my_strcpy(char* dest, const char* src) {while (*src != '\0') {*dest++ = *src++;}*dest = *src;   //拷贝\0
}namespace abl
{class string{//这里暂时还用不到友元,因为在operator>>中并没有访问string的私有成员//friend std::istream& operator>>(std::istream& in, string& s);private:size_t _size;size_t _capacity;char* _str;static size_t npos;public:typedef char* iterator;typedef const char* const_iterator;iterator begin(){return _str;//指向首元素}iterator end(){return _str + _size;//指向'\0'}const_iterator begin()const{return _str;}const_iterator end()const{return _str + _size;}string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_size + 1];memcpy(_str, str,_size+1);//完成初始化工作}~string(){//std::cout <<"::"<< _str << std::endl;delete[] _str;_str = nullptr;_size = _capacity = 0;std::cout << "~string()" << std::endl;}//现代写法string(const string& s):_str(nullptr),_size(0),_capacity(0){string tmp(s._str);//调用默认构造函数string(const char* str = "")swap(tmp);//this可能没有初始化,析构的时候就会报错,因此要写参数初始化列表}//string(const string& s)//{//	_str = new char[s._capacity + 1];//	memcpy(_str, s._str, s._size);//	_size = s._size;//	_capacity = s._capacity;//}void swap(string& tmp){std::swap(_str, tmp._str);std::swap(_size, tmp._size);std::swap(_capacity, tmp._capacity);}//现代写法string& operator= (string& s){if (this != &s){string tmp(s);//调用拷贝构造(深拷贝)swap(tmp);}return *this;}size_t size()const{return _size;}size_t capacity()const{return _capacity;}char& operator[](size_t pos){assert(pos <= _size);return _str[pos];}void reserve(size_t n = 0){//多留出一个空位给\0char* tmp = new char[n+1];//在堆区开辟空间,出函数不会销毁my_strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;//只改变了capacity,没有改变size,size不变}void push_back(char c){if (_size == _capacity){reserve(_capacity == 0 ? 6 : _capacity * 2);}_str[_size] = c;_size++;_str[_size] = '\0';}string& operator+= (char c){push_back(c);return *this;}string& operator+= (const char* s){size_t len = strlen(s);if (_size + len > _capacity){reserve(_size + len+10);}append(s);return *this;}string& append(const char* s){size_t len = strlen(s);if (_size + len > _capacity){reserve(_size + len + 1);}memcpy(_str + _size, s,len+1);_size += len;return *this;}string& insert(size_t pos, size_t n, char c){assert(pos <= _size);if (_size + n > _capacity){reserve(_size + n);}size_t end = _size+n;for (; end>=pos+n; end--){//abcd  size==4   pp  n==2  end==6  end-n==4_str[end] = _str[end-n];}for (size_t i = 0; i < n; i++){_str[pos + i] = c;}_size += n;return *this;}string& insert(size_t pos, const char* s, size_t n){assert(pos <= _size);size_t len = strlen(s);if (_size + n > _capacity){reserve(_size + n);}size_t end = _size + n;for (; end >= pos + n; end--)//当pos==0时,end>=pos恒成立,因为end为size_t类型,不可能是负数{//abcd  size==4   pp  n==2  end==6  end-n==4_str[end] = _str[end - n];}for (size_t i = 0; i < n; i++){_str[pos + i] = s[i];}_size += n;return *this;}//string& erase(size_t pos = 0, size_t len = npos)//{//}bool operator<(string& s)const{size_t i1 = 0, i2 = 0;//遍历两个字符串4while (i1 < _size && i2 < s._size){if (_str[i1] < s._str[i2]){return true;}else if (_str[i1] > s._str[i2]){return false;}else{i1++;i2++;}}//若循环正常进行结束,可能出现的情况://hello hello     return false//hellowwww hello return false//hello hellowww  return trueif (_size < s._size){return true;}return false;}bool operator==(string& s)const{//std::cout << s._size << std::endl;if (_size != s._size){return false;}return memcmp(_str, s._str, _size) == 0;}bool operator>(string& s)const{return !((*this < s) || (*this == s));}bool operator<=(string& s)const{return !(*this > s);}bool operator>=(string& s)const{return !(*this < s);}//string& operator= (const string& s)//{//	//开辟新空间,进行拷贝//	if (this != &s)//如果两个对象不相同//	{//		char* tmp = new char[s._capacity + 1];//		memcpy(tmp, s._str, s._size);//		delete[] _str;//		_str = tmp;//		_size = s._size;//		_capacity = s._capacity;//	}//	return *this;//}//void swap(string& str)//{//	//}//template<class T>//void swap(T m)//{//	T tmp = m;//	m = *this;//	*this = tmp;//}const char* c_str()const{return _str;}void clear(){_str[0] = '\0';_size = 0;}};
}
//std::ostream& operator<<(std::ostream& os, const abl::string& str)
//{
//	os << str._str << std::endl;
//	return os;
//}
size_t abl::string::npos = -1;//静态成员变量必须初始化,并且只能在类体外进行初始化
std::ostream& operator<<(std::ostream& out,const abl::string& str)
{for (auto ch : str){out << ch;}//out << str.c_str();return out;
}
std::istream& operator>>(std::istream& in, abl::string& s)
{s.clear();char bucket[128];//相当于一个桶,装满了再往s里边加,减少了开辟空间的次数,充分利用空间char c=in.get();int i = 0;while (c != ' ' && c != '\n'){bucket[i] = c;i++;if (i == 127){bucket[i] = '\0';//operator+=中要计算bucket的长度,以'\0'为终止条件,因此要在最后加上s += bucket;i = 0;//重新往buckt里边放入数据}c = in.get();}if (i != 0){bucket[i] = '\0';//...s += bucket;}return in;
}
2、string.cpp
#include <iostream>
#include <cstring>
#include "String.h"
using namespace std;void test_string1()
{abl::string s1("hello world");abl::string s2("legacy.cplusplus");string s3("jdksanxkdsd");string s4;cout << s3.c_str() << endl;cout << s4.c_str() << endl;cout << s1.c_str() << endl;for (size_t i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;cout << s2.c_str() << endl;abl::string::iterator it = s2.begin();while(it!=s2.end()){cout << *it << " ";++it;}cout << endl;cout << s2 << endl;
}
void test_string2()
{//string s1("hello");//cout << s1 << endl;//cout << s1.capacity() << endl;//abl::string s2("world");cout << s2.capacity() << endl;//s2.push_back('c');//s2.push_back('c');//s2.push_back('c');//cout << s2 << endl;//s2 += 's';//cout << s2 << endl;//s2 += "good";//cout << s2 << endl;abl::string s3("hello");s3.append(" judy");cout << s3 << endl;//abl::string s4("helloooo");s4 += '\0';//cout << s4 << endl;//s4 += "wwwwwww";//s4.insert(2, 3, 'y');//cout << s4 << endl;//abl::string s5("hello");//s5.insert(2, 5, 'p');//cout << s5 << endl;//s5.insert(9, "world", 6);//cout << s5 << endl;//for (auto ch : s5)//{//    cout << ch;//}//cout << endl;//string s6;//cin >> s6;//cout << s6 << endl;//cin >> s6;//cout << s6;/* cout << s4.npos << endl;*/
}
void test_string3()
{abl::string s1("hello");abl::string s2("helloxxxxx");//cout << (s2 < s1) << endl;abl::string s3("hello");//cout << (s1 == s2) << endl;//cout << (s1 == s3) << endl;cout << (s2 >= s3) << endl;cout << (s1 >= s2) << endl;cout << (s1 >= s3) << endl;
}
void test_string4()
{abl::string s1("helloxxxxxxxxxxx");//abl::string s2;//s2 = s1;//cout << s1 << endl;//cout << s2 << endl;//s1.append(" world");abl::string s2("worldxxx");s1 = s2;cout << s1 << endl;cout << s2 << endl;
}
int main()
{//test_string4();string s("hello world");string::iterator it = s.begin();while (it != s.end()){*it = 'x';it++;}cout << s << endl;return 0;
}

更多推荐

【C++

本文发布于:2023-11-16 13:10:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1623282.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!