#include <iostream>
#include <vector>
#include <memory>
#include <thread>
#include <type_traits>
#include <typeinfo>
#include <sstream>
#include <utility> class StrVec
{
friend std::ostream &operator<<(std::ostream &os, const StrVec &rhs); private:
std::string *elemnets_;
std::string *memry_free;
std::string *cap;
std::allocator<std::string> alloc;//为所有StrVec分配内存 //申请2倍范围空间,并把范围移动到新空间
std::pair<std::string *, std::string *> alloc_n_copy(const std::string *beg, const std::string *end)
{
auto new_memry = alloc.allocate(end - beg);
return {new_memry, std::uninitialized_copy(beg, end, new_memry)};
}; void free() //释放目前申请的内存
{
for (auto ptr = memry_free; ptr != elemnets_;)
{
alloc.destroy(--ptr);
} alloc.deallocate(elemnets_, memry_free - elemnets_);
} void realloctor() //重新申请大于目前2倍空间;
{
auto newcapacity = size() ? * size() : ;
auto newmemery = alloc.allocate(newcapacity);
auto dest = newmemery;
auto elem = elemnets_;//指向当前对象的头
for (size_t i = ; i != size(); ++i)
{
//move会让elem指向的string对象放弃自己的内存管理权并返回,然后construct使用string的移动构造函数构建dest指向的地址
alloc.construct(dest++, std::move(*elem++));
}
free();
elemnets_ = newmemery;
memry_free = dest;
cap = elemnets_ + newcapacity;
}; void Chk_n_alloc()
{
if (size() == capacity())
realloctor();
} public:
StrVec() : elemnets_(nullptr), memry_free(nullptr), cap(nullptr)
{} StrVec(std::initializer_list<std::string> li)
{
auto newadress = alloc_n_copy(li.begin(), li.end());
elemnets_ = newadress.first;
cap = memry_free = newadress.second;
} //只是构造(每次想着释放- -)
StrVec(const StrVec &rhs)
{
auto newadress = alloc_n_copy(rhs.begin(), rhs.end());
elemnets_ = newadress.first;
cap = memry_free = newadress.second;
} StrVec(StrVec &&rhs)
: elemnets_(rhs.elemnets_), memry_free(rhs.memry_free), cap(rhs.cap)
{
//置空
rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr;
} StrVec &operator=(const StrVec &rhs)
{
if (&rhs != this)
{
auto newadress = alloc_n_copy(rhs.begin(), rhs.end());
free();
elemnets_ = newadress.first;
memry_free = cap = newadress.second;
}
return *this;
} StrVec &operator=(StrVec &&rhs)
{
if (&rhs != this)
{
elemnets_ = rhs.elemnets_;
memry_free = rhs.memry_free;
cap = rhs.cap;
rhs.elemnets_ = rhs.cap = rhs.memry_free = nullptr;
}
return *this;
} //列表赋值初始化
StrVec &operator=(std::initializer_list<std::string> li)
{
auto newadress = alloc_n_copy(li.begin(), li.end());
free();
elemnets_ = newadress.first;
memry_free = cap = newadress.second; return *this;
} std::string &operator[](std::size_t size_)
{
return elemnets_[size_];
} std::string &operator[](std::size_t size) const
{
return elemnets_[size]; } bool operator==(const StrVec &s)
{
if (size() != s.size())
return false;
auto it = elemnets_, its = s.elemnets_;
while (it != memry_free)
{
if (*it++ != *its++)
return false;
}
return true;
} bool operator<(const StrVec &rhs)
{
if (this->size() < rhs.size())
{
return true;
} else if (this->size() > rhs.size())
{
return false;
} auto rhs_elemte = rhs.elemnets_;
for (auto iter_ptr = elemnets_; iter_ptr != memry_free;)
{
if (*iter_ptr++ > *rhs_elemte++)
{
return false;
} else
{
return true;
}
}
return false;
} bool operator>(const StrVec &rhs)
{
return !(*this < rhs) && (this != &rhs);
} bool operator!=(const StrVec &rhs)
{
return !(*this == rhs);
} public:
template<typename ...Args>
void emplace_back(Args &&... paracage)
{
Chk_n_alloc();
alloc.construct(memry_free++, std::forward<Args>(paracage)...);
} void push_back(const std::string &s)
{
Chk_n_alloc();//确保空间剩余
alloc.construct(memry_free++, s);//在尾后构建一个s(s的拷贝构造函数构造),并把尾后指针first_free指向下一个
} void pop_back()
{
if (memry_free != elemnets_)
{
alloc.destroy(--memry_free);
}
} std::size_t size() const
{
return memry_free - elemnets_;
} std::size_t capacity() const
{
return cap - elemnets_;
} std::string *begin() const
{
return elemnets_;
} std::string *end() const
{
return memry_free;
}
}; std::ostream &operator<<(std::ostream &os, const StrVec &rhs)
{
for (auto ptr = rhs.elemnets_; ptr != rhs.memry_free;)
{
os << *ptr++ << "\n";
} return os;
} int main(int argc, char *argv[])
{ StrVec strvec{"Hello", "World", "this", "std::string", "vector<std::string>"};
std::cout << strvec;
std::cout << strvec[] << std::endl;
strvec.push_back("你好");
std::cout << strvec[] << std::endl; std::cout << "------------" << std::endl;
std::cout << strvec;
strvec.pop_back();
strvec.pop_back();
strvec.pop_back();
strvec.pop_back();
std::cout << "------------" << std::endl;
std::cout<<strvec;
std::cout << "------------" << std::endl;
strvec.emplace_back("其实emeplace通过参数包转发给std::string的构造");
strvec.emplace_back(,'c');
std::cout<<strvec; return ;
}

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

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

    string.vector 互转 string 转 vector vector  vcBuf;string        stBuf("Hello DaMao!!!");----- ...

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

    最近在给自己的服务器框架加上统计信息,其中一项就是统计创建的对象数,以及当前还存在的对象数,那么自然以对象名字作key.但写着写着,忽然纠结是用std::string还是const char *作ke ...

  3. 基于std::string的字符串处理

    转自:http://zxdflyer.blog.163.com/blog/static/25664262201322510217495/ C++标准模板库std使用广泛.该库中处理字符串的对象为std ...

  4. std::string 字符串切割

    在很多字符串类库里都实现了split函数.不过在std里没有实现.在这里拿出几个: 1. 用单字符作为分隔 #include <string> #include <vector> ...

  5. std::string 字符串分割

    #include <iostream> #include <string> #include <vector> std::vector<std::string ...

  6. 单独删除std::vector <std::vector<string> > 的所有元素

    下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...

  7. C++ Primer学习笔记2--c++标准库中的 vector、string 和 bitset 类型

    一.string    #include <string>  using std::string    初始化函数:    string s1;        默认构造函数 s1 为空串 ...

  8. could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'

    VS2008, 写一个简单的demo的时候出现了这个: 1>------ Build started: Project: GetExportTable, Configuration: Relea ...

  9. 源码阅读笔记 - 3 std::string 与 Short String Optimization

    众所周知,大部分情况下,操作一个自动(栈)变量的速度是比操作一个堆上的值的速度快的.然而,栈数组的大小是在编译时确定的(不要说 C99 的VLA,那货的 sizeof 是运行时计算的),但是堆数组的大 ...

随机推荐

  1. Excel VBA宏 链接服务器 上传和下载数据

    首先说明以下. 第一: 下面的 “ _" 也就是 空格下划线 在VBA中表示换行的意思:& 表示链接连个字符串的操作,注意 & 的前后是否需要空格 第二: 如果链接服务器,服 ...

  2. Django_rest_framework_Serializer

    序列化Serializer 序列化用于对用户请求数据进行验证和数据进行序列化(为了解决queryset序列化问题). 那什么是序列化呢?序列化就是把对象转换成字符串,反序列化就是把字符串转换成对象 m ...

  3. 在虚拟机下安装Ubuntu

    目录: 1.安装虚拟机 2.在虚拟下安装Ubuntu 本文将按照目录分两步来讲一下在虚拟机下安装Ubuntu.第一步是安装虚拟机,第二步是在虚拟机下安装Ubuntu. 安装虚拟机 下载虚拟机链接以及激 ...

  4. Scrum Meeting 13 -2014.11.19

    最近数据库和编译的实验课也开始了,大家晚上的时间直接被砍掉了大部分. 希望大家能顺利完成项目吧.剩下时间也不多了,如果程序还存在一些特别的问题和需要优化修改的地方也应该考虑留到下阶段进行了. Memb ...

  5. connect by prior id= pid start with id='1' 树结构查询

    基础表创建: with temp as ( ' id, '' pid from dual union all ' pid from dual union all ' pid from dual uni ...

  6. 【DL.AI】《Structuring Machine Learning Projects》笔记

    一.改进模型的几个方法 Collect more data Collect more diverse training set Train algorithm longer with gradient ...

  7. FD.io 社区中国行暨未来网络技术沙龙 南京站 参会小结

    FD.io 社区中国行暨未来网络技术沙龙 南京站,2018 年 3 月 17 日. 开场致辞 Ray 介绍了一些有的没的 ⁃ (Future Event)DPDK summit, FD.io summ ...

  8. git学习(一) 如何将项目上传到github

    用了github有了段时间,但是感觉都是断断续续的,这次花了点时间来总结下,已方便下次忘记的时候拿出来看一下: 自己主要是参考了这个网站来学习的: git教程 -廖雪峰 第一步: 创建github账号 ...

  9. ubuntu中启动VIM,以及学习VIM

    启动VIM:首先打开终端,然后输入vi回车,然后输入i或者a,进入. 学习VIM:首先打开终端,然后输入vimtutor回车,然后进入教程学习.

  10. JS计算两个日期之间的天数,时间差计算

    1.日期之间的天数计算 //计算天数差的函数,通用 function DateDiff(sDate1, sDate2) { //sDate1和sDate2是2017-9-25格式 var aDate, ...