每日一言:"**心有繁星,皆为皓月。**🌸🌸"
上一章已经对string类进行了简单的介绍,大家只要能够正常使用即可。在面试中,面试官总喜欢让学生自己来模拟实现string类,最主要是实现string类的构造、拷贝构造、赋值运算符重载以及析构函数。
本文就主要针对该部分的源码进行剖析。
string.h
cpp
#include<assert.h>
#include<string.h>
//重新定义命名空间域以防与标准库冲突
namespace Poeir_
{
//封装string类
class string
{
public:
//迭代器
typedef char* iterator;
typedef const char* const_iterator;
iterator begin();
iterator end();
const_iterator begin() const;
const_iterator end() const;
//无参构造
string()
:_str(new char[1]{'\0'})
,_size(0)
,_capacity(0)
{}
//带参构造
string(const char* str)
:_str(new char[strlen(str)+1])
,_size(strlen(str))
_capacity(strlen(str))
{}
//上述代码效率不好,因为strlen是一个运行时调用的函数,时间复杂度是O(n)。
//字符串越长,时间开销越大,且容易因为声明顺序导致错误。
//也不能使用sizeof,因为它是编译时运算,但它只能运算数组,不能运算string。
//优化如下:将_str和_capacity放到内部初始化,防止初始化列表容易因为声明顺序导致错误。
string(const char* str = "")
:_size(strlen(str))
{
_capacity = _size;
_str = new char[_size + 1];
strcpy(_str,str);
}
//返回c风格字符串
//
const char* c_str() const
{
return _str;
}
//析构函数销毁字符串
~string ()
{
delete[] _str;
_str = nullptr;
_size = 0;
_capacity = 0;
}
//size()方法声明
size_t size() const;
//[]运算符重载声明
char& operator[](size_t i);//普通版
const char& operator[](size_t i) const;//const版
private:
char* _str;
//_size和_capacity都不包含'\0'
size_t _size;
size_t _capacity:
}
}
string.cpp
#include"string.h"
🔴一.size()方法
cpp
size_t string::size() const
{
return _size;
}
🔴二.[ ]运算符重载
cpp
char& string::operator[](size_t i)
{
assert(i < _size);
return _str[i];
}
cpp
const char& string::operator[](size_t i) const
{
assert(i<_size);
return _str[i];
}
🔴三.迭代器
begin()
cpp
string::iterator string::begin()//普通版
{
return _str;//返回首元素地址
}
cpp
string::const_iterator string::begin() const //const版
{
return _str;
}
end()
cpp
string::iterator string::end()//普通版
{
return _str + _size;//返回最后一个元素的地址
}
cpp
string::const_iterator string::end() const //const版
{
return _str + _size;
}
如有错误,恳请指正。