您的位置:首页 > 编程语言 > C语言/C++

C++primer学习:拷贝控制(6):编写简化的string类

2015-10-21 10:39 423 查看

利用allocator类编写自己的string类,实现的功能有:

(1)拷贝构造函数和普通构造函数,接受c字符串风格的参数

(2)重载了运算符,实现=,和+(拼接字符串)

(3)实现了4种查找函数,可以定义查找的起始位置(或者不定义),查找第一个出现的满足条件的字符或者第一个不满足的字符.

以及第一个出现在指定字符集的字符.全部返回迭代器.

(4)定义了相应的析构函数,和一些成员接口

(5)定义了提取子字符串的函数substr

(6)所有成员均可以处理越界的情况(如输入起始位置大于边界),同时注意保存字符’\0’.

#include "iostream"
#include "memory"
#include "utility"
#include "map"
#include "set"
#include "functional"
#include "vector"
#include "algorithm"
using namespace std;
class Str
{
public:
Str() :elements(nullptr), first_free(nullptr), cap(nullptr){}//默认构造函数
Str(const char * c);//接受字符串风格的参数
Str(const Str&);//拷贝构造函数
Str& operator= (const Str&);//拷贝赋值符号
~Str(){ free();}//析构函数
Str operator+(const Str&);//重载+运算符
Str substr(size_t pos, size_t len);//获取子字符串
Str substr(size_t pos){ return substr(pos,size());}//获取子字符串的重载形式
/*****************************查找成员**********************************/

char * find(const char ch){ find(0, ch); } //查找给定字符, 返回第一个字符所在的迭代器, 如果不存在, 返回尾后迭代器
char * find(size_t pos,const char ch); //从指定位置查找给定字符, 返回第一个字符所在的迭代器, 如果不存在, 返回尾后迭代器
char *find_not(const char ch){ find(0, ch); }//查找第一个不是ch的字符,返回所在的迭代器
char *find_not(size_t pos,const char ch);//从指定位置查找第一个不是ch的字符,返回所在的迭代器
char* find_fst_of(const char* ch){ find_fst_of(ch); }//查找第一个属于ch的字符,返回迭代器
char* find_fst_of(size_t pos, const char* ch);//查找第一个属于ch的字符,返回迭代器

/* *******************************  */
void print(){ if (elements)cout << elements << endl; }//输出指向的字符串
size_t size()const{ return first_free - elements; }
size_t length()const { return size() - 1; }
size_t capcity()const{ return cap - elements; }
char * begin()const{ return elements; }
char * end()const{ return first_free; }

private:
static allocator<char> alloc;
pair<char*, char*>alloc_n_copy(const char*,const  char*);

void free();
char *elements;
char* first_free;
char *cap;
};
allocator<char> Str:: alloc;
/*********public:**********/

Str::Str(const char * c)
{
auto newdata = alloc_n_copy(c, c + strlen(c)+1);//+1是为了把\0保存
elements = newdata.first;
first_free =cap = newdata.second;
}
Str::Str(const Str& s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
elements = newdata.first;
first_free = cap = newdata.second;
}
Str& Str:: operator= (const Str& s)
{
auto newdata = alloc_n_copy(s.begin(), s.end());
free();//释放旧的内存空间
elements = newdata.first;
first_free = cap = newdata.second;
return *this;
}
Str Str::operator+(const Str& s)
{
auto data = alloc.allocate(s.size()+size()-1);//动态分配内存
auto temp_end = uninitialized_copy(begin(), end(), data);//将内存拷贝到新分配的位置
auto real_end = uninitialized_copy(s.begin(), s.end()+1, temp_end-1);//注意上一个的结尾是\0,需要覆盖
return Str(data);
}
Str Str::substr(size_t pos, size_t len)
{
auto beg = elements + pos;
beg = beg<first_free ? beg : first_free;//不能超过有效位置
auto end = elements + pos + len;
end = end < first_free ? end : first_free;//不能超过有效位置
if (beg == end)//如果起始位置和终止位置一致,返回空字符
return Str();
auto newdata = alloc_n_copy(beg,end);
return Str(newdata.first);
}
char * Str::find(size_t pos,const char ch)//查找给定字符,返回第一个字符所在的迭代器,如果不存在,返回尾后迭代器
{
auto beg = begin()+pos;
beg = beg<first_free ? beg : first_free;//不能超过有效位置
for (; beg != end() && *beg != ch; ++beg){}
return beg;
}
char * Str::find_not(size_t pos,const char ch)
{
auto beg = begin()+pos;
beg = beg<first_free ? beg : first_free;//不能超过有效位置
for (; beg != end() && *beg == ch; ++beg){}
return beg;
}
char* Str::find_fst_of(size_t pos, const char* ch)
{
auto beg = begin() + pos;
beg = beg<first_free ? beg : first_free;//不能超过有效位置
set<char> is_of(ch, ch + strlen(ch));
for (; beg != end() && is_of.find(*beg) == is_of.end(); ++beg){}//通过set查找
return beg;
}
/************* private: ******************/
pair<char*, char*>Str::alloc_n_copy(const char*b,const char*e)
{
auto data = alloc.allocate(e-b);//动态分配内存
return{ data, uninitialized_copy(b, e, data) };//将内存拷贝到新分配的位置
}
void Str::free()
{
if (!elements)//不接受elements为空的情况
return;
for_each(elements, first_free, [](const char s) { alloc.destroy(&s);});
alloc.deallocate(elements, capcity());
}
void free();

int main()
{

Str a("mmbsad");
auto re = a + "fff"+"bbb";
re.print();
cout<<re.find_fst_of(0, "b");
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: