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

利用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++primer学习:拷贝控制(6):编写简化的string类)