1. 程式人生 > 其它 >【轉載】web 部署專題(一):Gunicorn執行與配置方法

【轉載】web 部署專題(一):Gunicorn執行與配置方法

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;