• C++ 实现vector<std:string> 版本


      1 #include <iostream>
      2 #include <vector>
      3 #include <memory>
      4 #include <thread>
      5 #include <type_traits>
      6 #include <typeinfo>
      7 #include <sstream>
      8 #include <utility>
      9 
     10 
     11 class StrVec
     12 {
     13     friend std::ostream &operator<<(std::ostream &os, const StrVec &rhs);
     14 
     15 private:
     16     std::string *elemnets_;
     17     std::string *memry_free;
     18     std::string *cap;
     19     std::allocator<std::string> alloc;//为所有StrVec分配内存
     20 
     21     //申请2倍范围空间,并把范围移动到新空间
     22     std::pair<std::string *, std::string *> alloc_n_copy(const std::string *beg, const std::string *end)
     23     {
     24         auto new_memry = alloc.allocate(end - beg);
     25         return {new_memry, std::uninitialized_copy(beg, end, new_memry)};
     26     };
     27 
     28 
     29     void free() //释放目前申请的内存
     30     {
     31         for (auto ptr = memry_free; ptr != elemnets_;)
     32         {
     33             alloc.destroy(--ptr);
     34         }
     35 
     36         alloc.deallocate(elemnets_, memry_free - elemnets_);
     37     }
     38 
     39     void realloctor()  //重新申请大于目前2倍空间;
     40     {
     41         auto newcapacity = size() ? 2 * size() : 1;
     42         auto newmemery = alloc.allocate(newcapacity);
     43         auto dest = newmemery;
     44         auto elem = elemnets_;//指向当前对象的头
     45         for (size_t i = 0; i != size(); ++i)
     46         {
     47             //move会让elem指向的string对象放弃自己的内存管理权并返回,然后construct使用string的移动构造函数构建dest指向的地址
     48             alloc.construct(dest++, std::move(*elem++));
     49         }
     50         free();
     51         elemnets_ = newmemery;
     52         memry_free = dest;
     53         cap = elemnets_ + newcapacity;
     54     };
     55 
     56     void Chk_n_alloc()
     57     {
     58         if (size() == capacity())
     59             realloctor();
     60     }
     61 
     62 public:
     63     StrVec() : elemnets_(nullptr), memry_free(nullptr), cap(nullptr)
     64     {}
     65 
     66     StrVec(std::initializer_list<std::string> li)
     67     {
     68         auto newadress = alloc_n_copy(li.begin(), li.end());
     69         elemnets_ = newadress.first;
     70         cap = memry_free = newadress.second;
     71     }
     72 
     73     //只是构造(每次想着释放- -)
     74     StrVec(const StrVec &rhs)
     75     {
     76         auto newadress = alloc_n_copy(rhs.begin(), rhs.end());
     77         elemnets_ = newadress.first;
     78         cap = memry_free = newadress.second;
     79     }
     80 
     81     StrVec(StrVec &&rhs)
     82             : elemnets_(rhs.elemnets_), memry_free(rhs.memry_free), cap(rhs.cap)
     83     {
     84         //置空
     85         rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr;
     86     }
     87 
     88     StrVec &operator=(const StrVec &rhs)
     89     {
     90         if (&rhs != this)
     91         {
     92             auto newadress = alloc_n_copy(rhs.begin(), rhs.end());
     93             free();
     94             elemnets_ = newadress.first;
     95             memry_free = cap = newadress.second;
     96         }
     97         return *this;
     98     }
     99 
    100     StrVec &operator=(StrVec &&rhs)
    101     {
    102         if (&rhs != this)
    103         {
    104             elemnets_ = rhs.elemnets_;
    105             memry_free = rhs.memry_free;
    106             cap = rhs.cap;
    107             rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr;
    108         }
    109         return *this;
    110     }
    111 
    112     //列表赋值初始化
    113     StrVec &operator=(std::initializer_list<std::string> li)
    114     {
    115         auto newadress = alloc_n_copy(li.begin(), li.end());
    116         free();
    117         elemnets_ = newadress.first;
    118         memry_free = cap = newadress.second;
    119 
    120         return *this;
    121     }
    122 
    123 
    124     std::string &operator[](std::size_t size_)
    125     {
    126         return elemnets_[size_];
    127     }
    128 
    129     std::string &operator[](std::size_t size) const
    130     {
    131         return elemnets_[size];
    132 
    133     }
    134 
    135 
    136     bool operator==(const StrVec &s)
    137     {
    138         if (size() != s.size())
    139             return false;
    140         auto it = elemnets_, its = s.elemnets_;
    141         while (it != memry_free)
    142         {
    143             if (*it++ != *its++)
    144                 return false;
    145         }
    146         return true;
    147     }
    148 
    149 
    150     bool operator<(const StrVec &rhs)
    151     {
    152         if (this->size() < rhs.size())
    153         {
    154             return true;
    155         } else if (this->size() > rhs.size())
    156         {
    157             return false;
    158         }
    159 
    160         auto rhs_elemte = rhs.elemnets_;
    161         for (auto iter_ptr = elemnets_; iter_ptr != memry_free;)
    162         {
    163             if (*iter_ptr++ > *rhs_elemte++)
    164             {
    165                 return false;
    166             } else
    167             {
    168                 return true;
    169             }
    170         }
    171         return false;
    172     }
    173 
    174     bool operator>(const StrVec &rhs)
    175     {
    176         return !(*this < rhs) && (this != &rhs);
    177     }
    178 
    179     bool operator!=(const StrVec &rhs)
    180     {
    181         return !(*this == rhs);
    182     }
    183 
    184 
    185 public:
    186     template<typename ...Args>
    187     void emplace_back(Args &&... paracage)
    188     {
    189         Chk_n_alloc();
    190         alloc.construct(memry_free++, std::forward<Args>(paracage)...);
    191     }
    192 
    193     void push_back(const std::string &s)
    194     {
    195         Chk_n_alloc();//确保空间剩余
    196         alloc.construct(memry_free++, s);//在尾后构建一个s(s的拷贝构造函数构造),并把尾后指针first_free指向下一个
    197     }
    198 
    199     void pop_back()
    200     {
    201         if (memry_free != elemnets_)
    202         {
    203             alloc.destroy(--memry_free);
    204         }
    205     }
    206 
    207 
    208     std::size_t size() const
    209     {
    210         return memry_free - elemnets_;
    211     }
    212 
    213     std::size_t capacity() const
    214     {
    215         return cap - elemnets_;
    216     }
    217 
    218     std::string *begin() const
    219     {
    220         return elemnets_;
    221     }
    222 
    223     std::string *end() const
    224     {
    225         return memry_free;
    226     }
    227 };
    228 
    229 
    230 std::ostream &operator<<(std::ostream &os, const StrVec &rhs)
    231 {
    232     for (auto ptr = rhs.elemnets_; ptr != rhs.memry_free;)
    233     {
    234         os << *ptr++ << "
    ";
    235     }
    236 
    237     return os;
    238 }
    239 
    240 
    241 int main(int argc, char *argv[])
    242 {
    243 
    244     StrVec strvec{"Hello", "World", "this", "std::string", "vector<std::string>"};
    245     std::cout << strvec;
    246     std::cout << strvec[3] << std::endl;
    247     strvec.push_back("你好");
    248     std::cout << strvec[5] << std::endl;
    249 
    250     std::cout << "------------" << std::endl;
    251     std::cout << strvec;
    252     strvec.pop_back();
    253     strvec.pop_back();
    254     strvec.pop_back();
    255     strvec.pop_back();
    256     std::cout << "------------" << std::endl;
    257     std::cout<<strvec;
    258     std::cout << "------------" << std::endl;
    259     strvec.emplace_back("其实emeplace通过参数包转发给std::string的构造");
    260     strvec.emplace_back(10,'c');
    261     std::cout<<strvec;
    262 
    263     return 0;
    264 }
  • 相关阅读:
    spring 配置 线程池并使用 springtest 进行测试
    Mybatis使用generator自动生成的Example类使用OR条件查询
    springtest mapper注入失败问题解决 {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    异常 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 解决方案
    idea 开启 tomcat 访问日志记录
    idea ssm项目迁移到另一台机器上时出现不能正常启动项目的解决方案
    记一次 java 连接 linux ssh服务 权限验证失败的原因和解决过程
    ajax传递数组给controller的实现方法和坑
    service手动实例化(new)导致类中的spring对象无法注入的问题解决
    javaweb学习总结十一(JAXP对XML文档进行DOM解析)
  • 原文地址:https://www.cnblogs.com/xuaidongstdudyrecording/p/7224500.html
Copyright © 2020-2023  润新知