C++ 实现vector<std:string> 版本
#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> 版本的更多相关文章
- 实战c++中的string系列--std:vector 和std:string相互转换(vector to stringstream)
string.vector 互转 string 转 vector vector vcBuf;string stBuf("Hello DaMao!!!");----- ...
- C++ std::unordered_map使用std::string和char *作key对比
最近在给自己的服务器框架加上统计信息,其中一项就是统计创建的对象数,以及当前还存在的对象数,那么自然以对象名字作key.但写着写着,忽然纠结是用std::string还是const char *作ke ...
- 基于std::string的字符串处理
转自:http://zxdflyer.blog.163.com/blog/static/25664262201322510217495/ C++标准模板库std使用广泛.该库中处理字符串的对象为std ...
- std::string 字符串切割
在很多字符串类库里都实现了split函数.不过在std里没有实现.在这里拿出几个: 1. 用单字符作为分隔 #include <string> #include <vector> ...
- std::string 字符串分割
#include <iostream> #include <string> #include <vector> std::vector<std::string ...
- 单独删除std::vector <std::vector<string> > 的所有元素
下面为测试代码: 1.创建 std::vector< std::vector<string> > vc2; 2.初始化 std::vector<string> vc ...
- C++ Primer学习笔记2--c++标准库中的 vector、string 和 bitset 类型
一.string #include <string> using std::string 初始化函数: string s1; 默认构造函数 s1 为空串 ...
- could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::string'
VS2008, 写一个简单的demo的时候出现了这个: 1>------ Build started: Project: GetExportTable, Configuration: Relea ...
- 源码阅读笔记 - 3 std::string 与 Short String Optimization
众所周知,大部分情况下,操作一个自动(栈)变量的速度是比操作一个堆上的值的速度快的.然而,栈数组的大小是在编译时确定的(不要说 C99 的VLA,那货的 sizeof 是运行时计算的),但是堆数组的大 ...
随机推荐
- SmartRaiden 和 Lighting Network 进行去中心化跨链原子资产交换
作者介绍 虫洞社区·签约作者 steven bai 前言 如果能够进行以太坊和比特币跨链原子资产交换,是不是一件很酷的事情? 目前链下的扩容方式有很多,最广为人知的就是比特币的闪电网络和以太坊的雷电网 ...
- MyBatis思维导图
1.初识框架技术 2.搭建MyBatis环境 3.掌握MyBatis的核心API 4.掌握MyBatis的核心配置文件:主要用于配置数据库连接和MyBatis运行时所需的各种特性 5.掌握SQL映射文 ...
- Node.js文档和教程
七天学会NodeJS:https://nqdeng.github.io/7-days-nodejs/ Node入门:http://www.nodebeginner.org/index-zh-cn.ht ...
- PHP中 post方法 与 get方法 的区别
1.Get 方法通过 URL 请求来传递用户的数据,将表单内各字段名称与其内容,以成对的字符串连接,置于 action 属性所指程序的 url 后,如[url]http://www.domain.co ...
- UVALive 7464 Robots(模拟)
7464Robots Write a program to collect data from robots. We are given two sets of robotsX=fX1;:::;Xmg ...
- Scrum立会报告+燃尽图(十二月五日总第三十六次):Final阶段分配任务
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://git.coding.net/zhang ...
- Java程序设计第四次实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程:java程序设计 班级:1352 姓名:何伟钦 学号:20135223 成绩: 指导教师:娄嘉鹏 ...
- 根据C#编程经验思考编程核心
程序是对数据的各种操作.数据的表示,数据的组织结构,数据的存储,数据的处理,数据的传输等. 程序是由具体的编程语言编写的,不同的编程语言有编写,编译检查,解释执行等过程. 具体的编程语言都有: 1,变 ...
- SQL Server查询已锁的表及解锁
--查询已锁的表 select request_session_id spid,OBJECT_NAME(resource_associated_entity_id) tableName ,* from ...
- Robot Framework 教程 (1) - 环境配置及简单网站兼容性测试
0.Robot Framework 简介 Robot Framework 是一个通用的自动化测试框架,主要用于“验收测试”和“验收测试驱动开发(ATDD)” (会其它文章中会详细介绍ATDD).它使用 ...