🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”
下面的这些是我们这篇文章将要实现的String的功能:
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
namespace bit
{
class string
{
public:
typedef char* iterator;
iterator begin();
iterator end();
string(const char* str = "");
~string();
const char* c_str() const;
size_t size() const;
char& operator[](size_t pos);
private:
char* _str;
size_t size;
size_t _capacity;
};
}
在这些功能当中
string(const char* str = "");
这样子写的目的主要是兼顾空的字符串,加入了缺省值,若是传入的字符串为空时候,会自动复制为“\0”
const char* c_str() const;
size_t size() const;
在这两行代码中,加入const主要是保证不管传入的size string是否可修改,都可以调用这两个函数。
上面的这些代码我们放到头文件当中。
而在.cpp文件中,我们用来实现这些功能。
#include"String.h"
在.cpp文件的开头我们引入头文件,有同学可能会好奇会不会和C++库当中的String.h文件发生冲突,但结果是不会的,因为编译器会现在当前目录进行查找,而当前目录就已经存在了这个文件。
#define _CRT_SECURE_NO_WARNINGS
#include"String.h"
namespace bit
{
string::iterator string::begin()
{
return _str;
}
string::iterator string::end()
{
return _str + _size;
}
string::string(const char* str)
:_size(strlen(str))
{
_str = new char[_size + 1];
_capacity = _size;
strcpy(_str, str);
}
string::~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
const char* string::c_str() const
{
return _str;
}
size_t string::size() const
{
return _size;
}
char& string::operator[](size_t pos)
{
assert(pos < _size);
return _str[pos];
}
}
这个便是基础的String的代码实现。
下面是针对这个String的测试文件
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include"String.h"
namespace bit
{
void test_string1()
{
bit::string s1("hello world");
cout << s1.c_str() << endl;
for (size_t i = 0; i < s1.size(); i++)
{
s1[i]++;
}
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1[i] << " ";
}
cout << endl;
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
for (auto e : s1)
{
cout << e << " ";
}
cout << endl;
bit::string s2;
cout << s2.c_str() << endl;
}
}
int main()
{
bit::test_string1();
return 0;
}
其实对于范围for而言,它的底层是迭代器,而迭代器,主要就是一个封装,底层的不同的类型都用iterator进行了重命名,搭建起来统一的上层建筑。
所以,只要搭建了基本的迭代器,范围for就可以使用了。