zoukankan      html  css  js  c++  java
  • c++ string类

    string类

    将StrVec类的一些变量进行全局替换就能得到String类
    1、string替换为char
    2、str替换为c,strs替换为c
    3、StrVec替换为String
    4、#include <string>替换为#include<cstring>

    StrVec和String就是类似的
    1、都是保存指向元素的指针,指向的空间都是在内中动态分配的。
    2、拷贝构造函数、拷贝赋值运算符拷贝StrVec(String)类的成员和指向的元素(拷贝赋值运算符有析构指向空间的过程)
    3、析构函数都是析构指针指向的空间。
    不同点:
    reallocate:

    • StrVec:是移动原空间的数据到新空间,释放原空间的string对象,不释放string指向的char元素(移动后原string指向的空间为nullptr)
    • String:移动char后,不会释放char
      原因是StrVec有两层指向,最基础的一层是不能销毁的,否则移动到新空间的数据被销毁了(这个地方还理解不清楚)

    String.h

    #include <cstring>
    #include <memory>
    #include <utility>           // pair move
    #include <initializer_list> // initializer_list
    #include <algorithm>         // for_each
    
    #ifndef STRVEC__H
    #define STRVEC__H
    
    using namespace std;
    
    class String {
        public:
            String():b(nullptr),e(nullptr),cap(nullptr){}
            String(const char *);
            String(const String &);
            String(String &&);
            String &operator=(const String &);
            String &operator=(String &&);
            ~String();
            
            void   push_back(const char &);
            size_t size() const {return e - b;}
            size_t capacity() const {return cap - b;}
            void   reserve(const size_t &);
            void   resize(const size_t &);
            void   resize(const size_t &, const char &);
            char *begin() const {return b;}
            char *end() const {return e;}
            
        private:
            static allocator<char> alloc;
            void chk_n_alloc() {if(size() == capacity()) reallocate();}
            pair<char*,char*> alloc_n_copy(const char*, const char*);
            void free();
            void reallocate();
            char *b;
            char *e;
            char *cap;
    }
    
    #endif
    

    String.cpp

    #include "String.h"
    
    // 静态成员变量定义和默认初始化。
    // 静态成员变量不属于任何对象,不能在类的构造函数中被构造和初始化,必须在类的外部定义和初始化
    // 不要重复写static
    // 静态函数可以在类内部定义(没有初始化一说)
    allocator<char> String::alloc; 
    
    
    
    String::String(const initializer_list<char> &c) {
        auto p = alloc_n_copy(c.begin(), c.end());
        b = p.first;
        e = cap = p.second;
    }
    
    String::String(const char *c) {
        auto p = alloc_n_copy(c, c+strlen(c));
        b = p.first;
        e = cap = p.second;
    }
    
    
    pair<char*,char*> String::alloc_n_copy(const char *b_ptr, const char *e_ptr) {
        auto p = alloc.allocate(e_ptr - b_ptr);
        return {p, uninitialized_copy(b_ptr, e_ptr, p)};
    }
    
    
    
    void String::free() {
        if(e) {
            for(auto p = e; p != b;)
                alloc.destroy(--p);
            alloc.deallocate(cap-b);
        }
    }
    
    
    
    
    
    
    void String::reallocate() {
        size_t newcapacity = size() ? 2*size() : 1; 
        auto p = alloc.allocate(newcapacity);
        auto dst = p;
        auto src = b;
        for(size_t i=0; i != size(); ++i)
            alloc.construct(dst++, std::move(*src++));
        b = p;
        e = dst;// p + size();
        cap = p + newcapacity;
        
    }
    
    
    String::String(const String &s) {
        auto p = alloc_n_copy(s.begin(), s.end());
        b = p.first;
        e = cap = p.second;
    }
    
    String::String(String &&s):b(s.b), e(s.e), cap(s.cap) {// 要修改s的内部成员,所以不能为const
        s.b = s.e = s.cap = nullptr;
    }
    
    String &String::operator=(const String &s) {
        auto p = alloc_n_copy(s.begin(), s.end());
        free();
        b = p.first;
        e = cap = p.second;
    }
    
    String &String::operator=(String &&s) {// 要修改s的内部成员,所以不能为const
        if(this != &s) {
            free();
            b = s.b;
            e = s.e;
            cap = s.cap;
            s.b = s.e = s.cap = nullptr;
        }
        
        return *this;
    }
    
    
    String::~String() {
        free();
    }
    
    
    void String::push_back(const char &c) {
        chk_n_alloc();
        alloc.construct(e++, c);
    }
    
    
    void String::resize(const size_t &n) {
        if(n > capacity()) {
            auto p = alloc.allocate(n);
            auto dst = p;
            auto src = b;
            size_t i = 0;
            for(; i != size(); ++i)
                alloc.construct(dst++, std::move(src++));
            for(; i != n; ++i)
                alloc.construct(dst++);
            free();
            b = p;
            e = cap = dst;
        } else if(n > size()) {    
            while(e < b+n)
                alloc.construct(e++);
        } else {    
            while(e > b+n)
                alloc.destroy(--e);
        }
    }
    
    
    
    void String::resize(const size_t &n, const char &c) {
        if(n > capacity()) {
            auto p = alloc.allocate(n);
            auto dst = p;
            auto src = b;
            size_t i = 0;
            for(; i != size(); ++i)
                alloc.construct(dst++, std::move(src++));
            for(; i != n; ++i)
                alloc.construct(dst++, c);
            free();
            b = p;
            e = cap = dst;
        } else if(n > size()) {    
            while(e < b+n)
                alloc.construct(e++, c);
        } else {
            while(e > b+n)
                alloc.destroy(--e);
        }
    }
    
    
    void String::reserve(const size_t &n) {
        if(capacity() < n) {
            auto p = alloc.allocate(n);
            auto dst = p;
            auto src = b;
            for(size_t i=0; i<size(); ++i)
                alloc.const(dst++, std::move(src++));
            free();
            b = p;
            e = dst;
            cap = b + n;
        }
    }
    

    测试代码

    String str("hello");
    for(const auto &v : str)
        cout<<v
    cout<<endl;
    
  • 相关阅读:
    串口 规格严格
    SWATCH 规格严格
    两个属性 规格严格
    ChinaUnix转载 规格严格
    Perl学习 规格严格
    3月5日工作日志88250
    使用NetBeans6开发OSGi应用(4)——Servlet与Http服务[88250原创]
    ごじゅうおん
    使用Apache Solr实现企业搜索
    3月6日工作日志88250
  • 原文地址:https://www.cnblogs.com/yuandonghua/p/15635905.html
Copyright © 2011-2022 走看看