文章目录
- string的介绍
- string的模拟实现
- string类的成员变量
- Member functions
- constructor(构造函数)
- destructor(析构函数)
- operator=(给创建出来的对象赋值)
- Iterators(迭代器)
- begin
- end
- Capacity
- size
- capacity
- reserve
- resize
- clear
- Element access
- operator[]
- Modifiers
- operator+=
- append
- push_back
- insert
- erase
- swap
- String operations
- c_str
- find
- Member constants
- npos
- Non-member function overloads
- operator>>
- operator<<
- 比较运算符重载
- 完整版string类代码
- string.h
- test.cpp
string的介绍
string是C++ STL库中一个重要的容器,它分为以下几个部分(将在vs编译器下实现)
Member function
Iterators
Capacity
Element access
Modifiers
String operations
Member constants
Non-member function overloads
在大家了解了string的每个部分的成员函数之后,我们就要去模拟实现每个部分之中在日常中经常使用到的一些成员函数。
string的模拟实现
string类的成员变量
Member functions
constructor(构造函数)
在这里我们主要实现构造函数常用的三种也就是图中的(1),(2),(4)
其中一写函数的注释代码,是代码优化前的写法,大家可以用来做参考和理解。
destructor(析构函数)
operator=(给创建出来的对象赋值)
在这里我们只实现第一种。
Iterators(迭代器)
在这里我们只实现了正向迭代器
由图片可以看出起始迭代器就只是一个被重新定义的指针。
begin
end
end和begin相似
Capacity
size
capacity
reserve
resize
resize功能和reserve一样但是多了个初始化和缩容
clear
Element access
operator[]
都是返回pos位置的字符
Modifiers
operator+=
这里只实现了(2)和(3)两个版本
append
push_back
insert
在这里指定位置插入函数就实现了2个常用的版本
erase
swap
String operations
c_str
find
Member constants
npos
Non-member function overloads
operator>>
operator<<
比较运算符重载
完整版string类代码
string.h
#pragma once
namespace lzy
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
iterator begin()
{
return _str;
}
const_iterator begin()const
{
return _str;
}
iterator end()
{
return _str + _size;
}
const_iterator end()const
{
return _str + _size;
}
//string s
string()
:_str(new char[1])
, _size(0)
, _capacity(0)
{
_str[0] = '\0';
}//创建一个空类
//string("hello world")
string(const char* s)
:_size(strlen(s))
, _capacity(_size)
{
_str = new char[_size + 1];
strcpy(_str, s);
}//用字符串初始化创建一个类
//string s1(s2)
string(const string& s)
//:_size(s._size)
:_size(0)
, _capacity(0)
{
/*_str = new char[_size+1];
strcpy(_str, s._str);*/
string temp(s._str);
swap(temp);
}//用类初始化创建一个类
~string()
{
delete[] _str;
}
//s1 = s2 = s3
//s1 = s1
void swap(string& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
//const string& operator=(const string& s)
//{
// if (&s != this)
// {
// //重新为数组开辟一块空间,不管空间是否足够
// delete[] _str;
// _str = new char[s._size + 1];
// //开始为这块新开辟的空间赋值
// for (int i = 0; i <= s._size; i++)
// {
// _str[i] = s._str[i];
// }
// _size = s._size;
// _capacity = s._capacity;
// }
// return *this;
//}
const string& operator=(string s)
{
//if (&s != this)
//{
// //重新为数组开辟一块空间,不管空间是否足够
// delete[] _str;
// _str = new char[s._size + 1];
// //开始为这块新开辟的空间赋值
// for (int i = 0; i <= s._size; i++)
// {
// _str[i] = s._str[i];
// }
// _size = s._size;
// _capacity = s._capacity;
//}
/*swap(_str, s._str);
swap(_size, s._size);
swap(_str, s._str);*/
swap(s);
return *this;
}
const char* c_str() const
{
return _str;
}
size_t size()const
{
return _size;
}
size_t capacity()const
{
return _capacity;
}
//s[i] 可修改
char& operator[](size_t pos)
{
//越界访问就报错
assert(pos < _size);
return *(_str + pos);
}
//s[i] const对象不可修改
const char& operator[](size_t pos)const
{
// 越界访问就报错
assert(pos < _size);
return *(_str + pos);
}
void reserve(size_t n)
{
if (n > _capacity)
{
char* temp = new char[n + 1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = n;
}
}
void resize(size_t n, char x = '\0')
{
if (n > _capacity)
{
char* temp = new char[n + 1];
memset(temp, x, n + 1);
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = n;
_size = n;
}
else
{
_size = n;
_str[_size] = '\0';
}
}
//尾插入一个字符
void push_back(char ch)
{
if (_size == _capacity)
{
//增容
/*size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
char* temp= new char[newcapacity+1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = newcapacity;*/
reserve(_capacity == 0 ? 4 : _capacity * 2);
}
_str[_size] = ch;
_size++;
_str[_size] = '\0';
}
//尾插入一段字符串
void append(const char* s)
{
size_t length = strlen(s);
//判断空间是否足够
if (_size + length > _capacity)
{
增容
//char* temp = new char[_size + length+1];
//strcpy(temp, _str);
//delete[] _str;
//_str = temp;
//_capacity = _size;
///*for (int i = 0; i <length; i++)
//{
// _str[i + _size] = s[i];
//}*/
// //增容
reserve(_size + length);
// for (int i = 0; i < length; i++)
// {
// _str[i + _size] = s[i];
// }
// _size += length;
//
//}
//else
//{
// for (int i = 0; i <length; i++)
// {
// _str[i + _size] = s[i];
// }
// _size += length;
// _str[_size] = '\0';
}
strcpy(_str + _size, s);
_size += length;
}
string& operator+=(char ch)
{
push_back(ch);
return *this;
}
string& operator+=(const char* s)
{
append(s);
return *this;
}
size_t find(char ch) const
{
for (size_t i = 0; i < _size; i++)
{
if (_str[i] == ch)
{
return i;
}
}
return npos;
}
size_t find(const char* s, size_t pos = 0)
{
char* temp = strstr(_str + pos, s);
if (temp == nullptr)
{
return npos;
}
return temp - _str;
}
string& insert(char ch, size_t pos)
{
if (_size == _capacity)
{
//增容
/*size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
char* temp = new char[newcapacity + 1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = newcapacity;*/
reserve(_capacity == 0 ? 4 : _capacity * 2);
}
size_t end = _size + 1;
while (pos < end)
{
_str[end] = _str[end - 1];
--end;
}
_str[pos] = ch;
_size++;
//_str[_size] = '\0';
return *this;
}
string& insert(const char* s, size_t pos)
{
assert(pos <= _size);
size_t len = strlen(s);
if (_size + len > _capacity)
{
//增容
/*size_t newcapacity = _size + len;
char* temp = new char[newcapacity + 1];
strcpy(temp, _str);
delete[] _str;
_str = temp;
_capacity = newcapacity;*/
reserve(_size + len);
}
size_t end = _size + len;
while (pos + len < end)
{
_str[end] = _str[end - len];
--end;
}
//_str[pos] = ch;
strcpy(_str + pos, s);
_size += len;
return *this;
}
string& erase(size_t pos, size_t len = npos)
{
assert(pos <= _size);
if (len == npos || pos + len > _size)
{
_str[pos] = '\0';
_size = pos;
}
else
{
//_str[pos] = '\0';
strcpy(_str + pos, _str + pos + len);
_size -= len;
}
return *this;
}
void clear()
{
_str[0] = '\0';
_size = 0;
}
private:
char* _str;
size_t _size;
size_t _capacity;
static size_t npos;
};
size_t string::npos = -1;
bool operator<(const string& s1, const string& s2)
{
size_t begin1 = 0, begin2 = 0;
while (begin1 < s1.size() && begin2 < s2.size())
{
if (s1[begin1] > s2[begin2])
{
return false;
}
else if (s1[begin1] < s2[begin2])
{
return true;
}
else
{
begin1++;
begin2++;
}
}
return begin2 < s2.size() ? true : false;
}
bool operator==(const string& s1, const string& s2)
{
return strcmp(s1.c_str(), s2.c_str());
}
bool operator>(const string& s1, const string& s2)
{
return !(s1 < s2 || s1 == s2);
}
bool operator<=(const string& s1, const string& s2)
{
return !(s1 > s2);
}
bool operator>=(const string& s1, const string& s2)
{
return !(s1 < s2);
}
ostream& operator<<(ostream& out, const string& s)
{
///*out << s.c_str();*/不能这么写
for (auto e : s)
{
out << e;
}
return out;
}
istream& operator>>(istream& in, string& s)
{
s.clear();
char ch = in.get();
while (ch != '\n')
{
//s += ch;
s += ch;
ch = in.get();
}
return in;
}
void test_string1()
{
string s1;
string s2("hello world");
string s3(s2);
s1 = s2;
s2 = s2;
cout << s1.c_str() << endl;
cout << s1.size() << endl;
//cout << s1[s1.size() - 1] << endl;
cout << s1[s1.size()] << endl;
}
void test_string2()
{
string s1;
s1.push_back('H');
s1.append("ell");
s1.append("o world");
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
it++;
}
//s1.reserve(1000);
//s1.resize(100);
/*s1 += ' ';
s1 += "hello mom";*/
}
void test_string3()
{
string s1;
/*s1.push_back('H');
s1.append("ell");
s1.append("o world");*/
s1.insert('H', s1.size());
s1.insert("ell", s1.size());
s1.insert("o world", s1.size());
string::iterator it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
it++;
}
cout << endl;
cout << s1.find('H') << endl;
cout << s1.find("world") << endl;
//s1.erase(0);
s1.erase(5, 1);
//s1.erase(0, 6);
it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
it++;
}
cout << endl;
/*string s2(s1);
it = s2.begin();
while (it != s2.end())
{
cout << *it << " ";
it++;
}
cout << endl;*/
}
void test_string4()
{
string s1("abcd");
//string s2("abcd");
string s3("abcde");
/*cout << (s1 < s2) << endl;
cout << (s1 < s3) << endl;*/
/*cout << (s1 == s3) << endl;
cout << (s1 == s2) << endl;*/
/*s1 += '\0';
s1 += "hello";*/
/*cout << s1 << endl;
string s2;
cin >> s2;
cout << s2;*/
//s1.clear();
cout << s1;
}
}
test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<string>
#include<assert.h>
#include"string.h"
int main()
{
lzy::test_string1();
//lzy::test_string2();
//lzy::test_string3();
//lzy::test_string4();
return 0;
}
vs编译器下的实现