写了一个元素是string的vector容器,用到了不少知识点
头文件
#ifndef _StrVec_H
#define _StrVec_H
#include<memory>
#include<string>
#include<utility>
#include<initializer_list>
#include<iostream>
class StrVec{
public:
StrVec():element(nullptr),first_free(nullptr),cap(nullptr){ }
StrVec(std::initializer_list<std::string>l);
StrVec(const StrVec&);
StrVec& operator=(const StrVec&)&;
StrVec(StrVec&& p)noexcept:element(p.element),first_free(p.first_free),cap(p.cap){p.element=p.first_free=p.cap=nullptr; std::cout<<"StrVec(StrVec&&)"<<std::endl;}
StrVec& operator=(StrVec &&s)& noexcept ;
~StrVec();
void push_back(const std::string&);
void push_back(std::string&&);
size_t size()const {return first_free-element;}
size_t capacity()const{return cap-element;}
std::string* begin()const{return element;}
std::string* end()const {return first_free;}
private:
std::string* element;
std::string* first_free;
std::string* cap;
std::allocator<std::string>alloc;
void chk_n_alloc();
std::pair<std::string*,std::string*>alloc_n_copy(const std::string*,const std::string*);
void free();
void reallocate();
};
#endif
源文件
#include"StrVec.h"
using namespace std;
std::pair<std::string*,std::string*>StrVec::alloc_n_copy(const std::string* b,const std::string* e){
auto data=alloc.allocate(e-b);
return {data,uninitialized_copy(b,e,data)};
}
void StrVec::free(){
if(element){
for(auto p=first_free;p!=element;)
alloc.destroy(--p);
alloc.deallocate(element,cap-element);
}
}
void StrVec::reallocate(){
auto newcapacity=size()? 2*size():1;
auto newdata=alloc.allocate(newcapacity);
auto dest=newdata;
auto elem=element;
for(size_t i=0;i!=size();++i)
alloc.construct(dest++,std::move(*elem++));
free();
element=newdata;
first_free=dest;
cap=first_free+newcapacity;
}
void StrVec::chk_n_alloc(){
if(capacity()==size())
reallocate();
}
void StrVec::push_back(const std::string& s){
chk_n_alloc();
alloc.construct(first_free++,s);
}
StrVec::StrVec(const StrVec& s){
auto newdata=alloc_n_copy(s.begin(),s.end());
element=newdata.first;
first_free=cap=newdata.second;
cout<<"StrVec(const StrVec&)"<<endl;
}
StrVec& StrVec::operator=(const StrVec& s)&{
auto data=alloc_n_copy(s.begin(),s.end());
free();
element=data.first;
first_free=cap=data.second;
cout<<"operator=(const StrVec&)"<<endl;
return *this;
}
StrVec::~StrVec(){
free();
}
StrVec::StrVec(std::initializer_list<std::string>l){
auto data=alloc.allocate(l.size());
auto p=uninitialized_copy(l.begin(),l.end(),data);
element=data;
first_free=cap=p;
}
StrVec& StrVec::operator=(StrVec &&s)& noexcept {
if(&s!=this){
free();
element=s.element;
first_free=s.first_free;
cap=s.cap;
s.element=s.first_free=s.cap=nullptr;
}
cout<<"operator=(StrVec&&)"<<endl;
return *this;
}
void StrVec::push_back(std::string&& s){
chk_n_alloc();
alloc.construct(first_free++,std::move(s));
}
测试例程
#include"StrVec.h"
#include<iostream>
using namespace std;
int main(){
StrVec v={"jordan","kobe","james"};
// for(auto b=v.begin();b!=v.end();++b)
// cout<<*b<<" ";
StrVec v1=v;
StrVec v2=std::move(v1);
v2=v;
StrVec v3;
v2=std::move(v3);
return 0;
}
就酱