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++ << "\n";
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 }
时间: 2024-08-26 13:27:53

C++ 实现vector<std:string> 版本的相关文章

实战c++中的string系列--std:vector&lt;char&gt; 和std:string相互转换(vector to stringstream)

有时候也会遇到std:vector与转std:string 相互转换的情况. 首先看一下vector<char>如何转string: std::vector<char> *data = response->getResponseData(); std::string res; //方法一 for (int i = 0;i<data->size();++i) { res+=(*data)[i]; } res+='\0'; std:cout << res;

实战c++中的string系列--std:vector 和std:string相互转换(vector to stringstream)

string.vector 互转 string 转 vector vector  vcBuf;string        stBuf("Hello DaMao!!!");----------------------------------------------vcBuf.resize(stBuf.size());vcBuf.assign(stBuf.begin(), stBuf.end()); vector 转 string  stBuf.clear();stBuf.assign(v

C++ std::unordered_map使用std::string和char *作key对比

最近在给自己的服务器框架加上统计信息,其中一项就是统计创建的对象数,以及当前还存在的对象数,那么自然以对象名字作key.但写着写着,忽然纠结是用std::string还是const char *作key,哪个效率高些.由于这服务器框架业务逻辑全在lua脚本,在C++需要统计的对象没几个,其实用哪个没多大区别.我纠结的是,很久之前就知道这两者效率区别不大,但直到现在我都还没搞清楚为啥,于是写些代码来测试. V1版本的代码如下: #ifndef __MAP_H__ #define __MAP_H__

std::string源码探秘和性能分析

std::string源码探秘和性能分析 本文主要讲c++标准库的string的内部实现,以及对象拷贝的性能分析. 文中采用的源码版本为gcc-4.9,测试环境为centos7, x86_64,涉及到指针等数据类型的大小也假定是在64环境位下. stl源码可以在gnu gcc的官方网站下载到:https://gcc.gnu.org/ 头文件 vector头文件,该文件也可以直接在安装了g++的linux系统中找到.主要包含以下头内容: // vector #include <bits/strin

实战c++中的vector系列--使用sort算法对vector&lt;unique_ptr&lt;string&gt;&gt;进行排序(sort函数出错“应输入 2 个参数,却提供了 3 个)

之前博客写了对vector使用sort算法进行的排序,之前也写到过vector<unique_ptr<string>>的一些处理方法. 今天就写一下对vector<unique_ptr<string>>使用sort算法进行排序. #include<iostream> #include<string> #include<vector> #include<algorithm> #include<memory&

c++ istream转换为std::string

std::istreambuf_iterator<char> eos; std::string s(std::istreambuf_iterator<char>(stream), eos);---------------------------------------------------------------------------- (could be a one-liner if not for MVP) post-2011 edit, this approach is

源码阅读笔记 &ndash; 3 std::string 与 Short String Optimization

众所周知,大部分情况下,操作一个自动(栈)变量的速度是比操作一个堆上的值的速度快的.然而,栈数组的大小是在编译时确定的(不要说 C99 的VLA,那货的 sizeof 是运行时计算的),但是堆数组的大小在运行时确定,很自由.此外,栈空间比堆空间有限,前者只有几MB,而后者基本上就是你系统内存的大小. 正因为这样,我们想组合两者的优势,既要享受堆空间的自由,又想要在数组较小的时候使用栈空间来加快速度,并且结合两者不会产生额外的开销,这时候,我们需要Short String Optimization

boost::interprocess::managed_shared_memory(2)(std::string)

#include <iostream> #include <boost/interprocess/managed_shared_memory.hpp> #include <boost/interprocess/allocators/allocator.hpp> #include <boost/interprocess/containers/string.hpp> using namespace std; int main() { //boost::inter

C++: std::string 与 Unicode 如何结合?

关键字:std::string Unicode 转自:http://www.vckbase.com/document/viewdoc/?id=1293 一旦知道 TCHAR 和_T 是如何工作的,那么这个问题很简单.基本思想是 TCHAR 要么是char,要么是 wchar_t,这取决于_UNICODE 的值: 1: // abridged from tchar.h 2:  3: #ifdef _UNICODE 4:  5: typedef wchar_t TCHAR; 6:  7: #defi