头文件
#include<iostream>
#include<assert.h>
using namespace std;
namespace bit
{
class string
{
public:
string(const char* str=""); //构造
string(const string& str); //拷贝构造
char* c_str()const; //转换成为字符串
size_t size()const; //元素个数
char operator[](size_t pos)const;
string& operator=(const string& str);
void reserve(size_t n); //reserve:预留,为string预留n的容量
void push_back(const char ch);
void push_back(const char* str);
void insert(size_t pos, const char ch);
void operator+=(const char*str);
void operator+=(const char ch);
void erase(size_t pos, int len);
size_t find(size_t pos, char ch);
string substr(size_t pos, int len);
void clear();
void swap(string &s);
private:
char* _str;
size_t _size;
size_t _capacity;
};
ostream& operator<<(ostream& os, const string& str);
istream& operator>> (istream& is, string& str);
}
源文件
#include"string.h"
namespace bit
{
string::string(const char* str)
:_size(strlen(str))
{
_str = new char[_size+1];
_capacity = _size;
strcpy(_str, str);
}
string::string(const string& str)
{
_str = new char[str._size];
_size = str._size;
_capacity = str._capacity;
strcpy(_str, str._str);
}
char* string::c_str()const
{
return _str;
}
size_t string::size()const
{
return _size;
}
char string::operator[](size_t pos)const
{
assert(pos < _size);
return _str[pos];
}
string& string::operator=(const string& str)
{
if (this!= &str)
{
_capacity = str._capacity;
_size = str._size;
char* temp = new char[str._size + 1];
strcpy(temp, str._str);
delete[]_str;
_str = temp;
}
return *this;
}
void string::reserve(size_t n)
{
if (n > _capacity)
{
char* temp = new char[n + 1];
delete _str;
_str = temp;
_capacity = n;
}
}
void string::push_back(const char ch)
{
if (_size == _capacity)
{
_capacity = (_capacity == 0 ? 4 : 2 * _capacity);
reserve(_capacity);
}
_str[_size ] = ch;
_str[_size + 1] = '\0';
_size++;
}
void string::push_back(const char* str)
{
size_t n = strlen(str);
if (_size == _capacity)
{
_capacity = (_capacity == 0 ? 4 : 2 * _capacity)+n;
reserve(_capacity);
}
for (int i = 0; i < n; i++)
{
_str[_size + i] = str[i];
}
_size += n;
_str[_size + 1] = '\0';
}
void string::insert(size_t pos, const char ch)
{
if (_size == _capacity)
{
_capacity = (_capacity == 0 ? 4 : 2 * _capacity);
reserve(_capacity);
}
for (size_t i = _size; i > pos; i--) //
{
_str[i] = _str[i - 1];
}
_str[pos] = ch;
_size++;
_str[_size] = '\0';
}
void string::operator+=(const char*str)
{
if (_size == _capacity)
{
_capacity = (_capacity == 0 ? 4 : 2 * _capacity);
reserve(_capacity);
}
push_back(str);
}
void string::operator+=(const char ch)
{
if (_size == _capacity)
{
_capacity = (_capacity == 0 ? 4 : 2 * _capacity);
reserve(_capacity);
}
push_back(ch);
}
void string::erase(size_t pos, int len)
{
assert(pos < _size);
if (pos+len>_size)
{
_str[pos + 1] = '\0';
}
else
{
for (int i = 0; i <pos+len; i++)
{
_str[pos + i] = _str[pos + len + i];
}
}
_size -= len;
}
size_t string::find(size_t pos, char ch)
{
for (size_t i = pos; i < _size; i++)
{
if (_str[i] == ch)
{
return i;
}
}
return std::string::npos;
}
string string::substr(size_t pos, int len)
{
if (len > _size - pos)
{
string sub(_str + pos);
return sub;
}
else
{
string sub;
sub.reserve(len);
for (size_t i= pos; i < len; i++)
{
sub += _str[pos + i];
}
return sub;
}
}
ostream& bit::operator<< (ostream& os, const string& str)
{
for (size_t i = 0; i < str.size(); i++)
{
os << str[i];
}
return os;
}
void string::clear()
{
_str[0] = '\0';
_size = 0;
_capacity = 0;
}
istream& bit::operator>> (istream& is, string& str)
{
str.clear();
char ch = is.get();
while (ch != ' ' && ch != '\n')
{
str += ch;
ch = is.get();
}
return is;
}
void string::swap(string& s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
}
测试文件
#include"string.h"
void test01()
{
bit::string s1("hello world");
const bit::string s2(s1);
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
cout << s2.size() << endl;
cout << s2[1] << endl;
}
void test02()
{
bit::string s1("hello world");
bit::string s2 = s1;
cout << s1.c_str() << endl;
}
void test03()
{
bit::string s1("hello world");
s1.push_back('x');
cout << s1.c_str() << endl;
bit::string s2;
for (int i = 0; i < 10; i++)
{
s2.push_back('x');
}
cout << s2.c_str() << endl;
bit::string s3("hello world");
s3.push_back("hello world");
cout << s3.c_str() << endl;
}
void test04()
{
bit::string s1("hello world");
s1.insert(5, 'x');
cout << s1.c_str() << endl;
bit::string s2("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
//s2.insert(0, 'h');
cout << s2.c_str() << endl;
}
void test05()
{
bit::string s1("hello world");
s1 += " hello world";
cout << s1.c_str() << endl;
s1 += 'x';
cout << s1.c_str() << endl;
}
void test06()
{
bit::string s1("One day I will be a successful person");
s1.erase(0, 8);
cout << s1.c_str() << endl;
}
void test07()
{
bit::string s1("One day I will be a successful person");
cout << s1.find(0, 'I') << endl;
cout << s1.find(0, 'z')<<endl;
}
void test08()
{
bit::string s1("One day I will be a successful person");
cout << s1.substr(8, 100).c_str()<<endl;
cout << s1 << endl;
}
void test09()
{
bit::string s1("hello world");
cin >> s1;
cout << s1 << endl;
}
int main()
{
test09();
return 0;
}
几点说明
swap()函数
其实对于上面的swap()函数,可以调用标准库里面的函数
使用的话,就像下面的那样使用
这也成功的交换了
但是这里有一个问题,就是你没有发现这样的代价有点大吗
这里需要创建一个临时的对象,特别是对于这里自定义类型,需要临时开辟一块空间,将_str里面的东西拷贝到这个临时对象里面去,太麻烦了
所以这里我们可以从重新写一个,只需要交换指向,指针变量交换指向,整形变量交换值
但是凡是不要慌,C++的string类里面是有swap()函数的
直接向下面的这样用就可以了
关于提取流函数
这里用的是istream里面get函数,这里是不能用cin或者scanf函数的
就是这里用cin的话,是不能提取到空格的,下面的程序输入了5个x,但是实际输出的只有一个,说明cin在这里,遇到了空格就停止了
scanf函数同样是如此
关于拷贝构造函数
上面有两种写法,一种是传统写法,使用的是深拷贝,另外一种是借助他人的力量,两种写法在消耗上面没有任何差别,在string优点很少,目前发现的就是干净简洁,安全,因为是借助编译器自动调用构造和析构函数,而不需要手动的去开辟和释放资源,所以安全,但是在链表部分会有很大的帮助,在链表部分如果你要拷贝构造,你一个一个的拷贝就有些麻烦,直接像下面这样不是更好(具体我们在链表部分再说)
上面需要注意的是,swap函数必须要使用引用传值,使用传值传参的话会诱发无穷递归
这个会在2,3步之间无限循环
赋值重载的现代写法