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; }
相关文章推荐
- C语言标准库常见函数的内部实现
- C++的try、catch、throw异常
- 面试中的C++常见问题
- 第三章 Data语意学
- C语言之指针
- c语言读写文件
- C/C++中各种类型int、long、double、char表示范围(最大最小值)
- 记录-C和指针-第十章-结构和联合
- c++ Map使用
- 线性方程组(A是上三角矩阵时)的C++求解
- C++与python中关于程序运行时的计量
- c++字符窜切割
- 推荐一个c++小巧开源且跨平台的图像解码库
- 推荐一个c++小巧开源且跨平台的图像解码库
- Static用法总结
- C++11 的一些有用的特性1 VS2012可支持
- 待解决的问题 --- C++
- 学习C语言第二天
- C++ Boost 好资源
- c++ iterator