#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. [朴孝敏][Road Trip]

    歌词来源:http://music.163.com/#/song?id=406907305 作曲 : Ryan S. Jhun/G'harah 'PK' Degeddingseze/Denzil Re ...

  2. poweroff命令详解

    2019-02-17  基础命令学习目录首页   原文链接:https://www.cnblogs.com/Baron-Lu/p/6951297.html 在本篇中,我们会向你解释 shutdown. ...

  3. BugPhobia开发篇章:Scurm Meeting-更新至0x02

    0x01 :目录与摘要 If you weeped for the missing sunset, you would miss all the shining stars 索引 提纲 整理与更新记录 ...

  4. web153

    电影网站:www.aikan66.com 项目网站:www.aikan66.com 游戏网站:www.aikan66.com 图片网站:www.aikan66.com 书籍网站:www.aikan66 ...

  5. BufferedWriter与BufferedRead --------------------------Test

    package com.test; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; ...

  6. 文件名命工具类(将指定目录下的文件的type类型的文件,进行重命名,命名后的文件将去掉type)

    import java.io.File; /** * <b>function:</b> 文件命名工具类 * @author hoojo * @createDate 2012-5 ...

  7. POJ 1112 Team Them Up! 二分图判定+01背包

    题目链接: http://poj.org/problem?id=1112 Team Them Up! Time Limit: 1000MSMemory Limit: 10000K 问题描述 Your ...

  8. build.xml

    下载ant 解压ant 后设置ANT_HOME, PATH中添加ANT_HOME目录下的bin目录(如:ANT_HOME:,PATH:D:\apache-ant-1.9.2%ANT_HOME%\bin ...

  9. SQLSERVER 升级版本的方法

    1. 以SQLSERVER2014为例说明 SQLSERVER升级版本的方法, 也适用于evaluation 版本超过180天之后的处理. 2. 打开所有的应用 看到有一个 sqlserver2008 ...

  10. 探秘SpringAop(一)_介绍以及使用详解

    常用的编程范式 AOP 是什么 是一种编程方式,不是编程语言 解决特定问题,不能解决所有的问题 OOP的补充,不是代替 AOP 初衷 DRY: Don't repeat yourself(代码重复) ...