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 是运行时计算的),但是堆数组的大 ...
随机推荐
- Classifier
1.视频:https://morvanzhou.github.io/tutorials/machine-learning/keras/2-2-classifier/ 2.敲了代码,但是运行结果不懂,明 ...
- java代码生成xml 报错:HIERARCHY_REQUEST_ERR: 尝试在不允许的位置插入节点。
document.appendChild(controlElement)好像只能append一个根节点
- crontab任务不生效
新建php脚本ctTest.php,代码如下: <?php /****************************************************************** ...
- 解决Cygwin编译cocos2dx 遇到的 error: 'UINT64_C' was not declared in this scope 问题
环境工具:Win10.VS2013.cocos2d-x-2.2.6.Cygwin.ADT 问题来源:写了一个小游戏,VS2013上运行成功,就尝试着打包apk,项目导入到ADT里面,添加了cocos2 ...
- 寒假作业第二篇随笔(A+B)
Github链接:https://github.com/heihuifei/object-oriented A+B Format (20) Calculate a + b and output the ...
- myeclipse 导入 import maven web project
用google才收到了这个.. http://stackoverflow.com/questions/12197662/maven-java-web-project-not-recognised-wh ...
- sprint初步计划(第一天)
一.现状 小组成员初步了解四则运算程序编写大概内容,进行简单的讨论.只知道大概的流程,实际还没做出.现在明确目标是把我们写Java的四则运算变成一个手机APP,关于手机ap,我们还不是很了解,所以需要 ...
- 关于Keil C关键字xdata和data的问题
1.xdata表示这是一个外部RAM地址内的数据,数据最终将被保存至外部RAM的某个地址单元中:但是,外部RAM只能通过寄存器间接寻址来访问,也就是说,其地址需要保存在内部RAM中(其实或许是SFR中 ...
- vue之Mutations 理解
commit:提交可以在组件中使用 this.$store.commit('xxx') 提交 mutation,或者使用 mapMutations 辅助函数将组件中的 methods 映射为 stor ...
- 第四周PSP&进度条
团队项目PSP 一:表格 C类型 C内容 S开始时间 E结束时间 I时间间隔 T净时间(mins) 预计花费时间(mins) 讨论 讨论开发环境.工具以及技术 8:37 10:42 25 10 ...