
定义向量容器Vector是一种动态数组在C 标准模板库STL中定义为std::vector。它可以存储相同类型的元素并且能够根据需要自动调整大小。templatetypenameTclassmyvector{public:myvector(intsize10);~myvector();myvector(constmyvectorTrhs);voidoperator(constmyvectorTrhs);voidpush_back(constTval)// 给末尾添加元素{if(full()){resize();}*last_val;}voidpop_back()// 删除末尾元素{if(empty()){return;}last_--;}boolfull()const{returnlast_end_;}boolempty()const{returnfirst_last_;}voidshow()const{for(T*pfirst_;p!last_;p){cout*p ;}coutendl;}private:voidresize()// 2倍的扩容函数 windows vs 1.5倍扩容 linux gcc 2倍扩容{intsizeend_-first_;T*new_firstnewT[size*2];T*new_lastnew_first;T*pextfirst_;while(pext!last_){*new_last*pext;new_last;pext;;}delete[]first_;first_new_first;last_new_last;end_first_size*2;}private:T*first_;// 指向首元素位置T*last_;// 指向最后一个元素的后继位置T*end_;// 指向内存的后继位置};templatetypenameTmyvectorT::myvector(intsize){first_newT[size];last_first_;end_first_size;}templatetypenameTmyvectorT::~myvector(){delete[]first_;first_nullptr;}templatetypenameTmyvectorT::myvector(constmyvectorTrhs){intsizerhs.end_-rhs.first_;first_newT[size];last_first_;end_first_size;T*pextrhs.first_;while(pext!rhs.last_){*last_*pext;last_;pext;}}templatetypenameTvoidmyvectorT::operator(constmyvectorTrhs){if(thisrhs){return;}delete[]first_;intsizerhs.end_-rhs.first_;first_newT[size];last_first_;end_first_size;T*pextrhs.first_;while(pext!rhs.last_){*last_*pext;last_;pext;}}问题容器刚创建还没有有效元素就构造大量多余对象push_back 添加元素使用赋值而不是拷贝构造对象pop_back 仅仅移动指针不调用析构函数会造成资源泄漏。扩容 resize 的时候产生大量无用默认对象迁移元素使用赋值而非拷贝构造析构函数 delete [] 会析构全部 capacity 个对象包含逻辑无效的多余对象总结这份代码把「内存分配」和「对象构造」混在一起了STL vector 通过 allocator 把两件事拆开allocate分配未初始化裸内存只有字节没有对象construct在已经分配好的裸内存上调用构造函数创建对象destroy调用析构销毁对象不释放内存deallocate释放裸内存不调用析构拷贝构造函数仅在创建新对象的时刻被调用此时不存在已存在的同类型目标对象。赋值运算符重载仅在两个都已经创建完成的对象之间执行赋值操作时被调用不会创建新对象而是修改已有左值对象的内部状态。析构函数在对象生命周期彻底结束的时刻被调用是对象销毁前执行的最后一个成员函数。修改后templatetypenameTstructAllocator{T*allocator(size_t size){//分配内存return(T*)malloc(sizeof(T)*size);}voiddeallocator(T*addr){//释放内存free(addr);}voidconstruct(T*addr,constTobj){//创建对象new(addr)T(obj);}voiddestroy(T*addr){//销毁对象addr-~T();}};templatetypenameTclassmyvector{public:myvector(intsize4){first_allocator_.allocator(size);last_first_;end_first_size;}~myvector(){//1.析构 2.释放内存for(T*pfirst_;p!last_;p){allocator_.destroy(p);}allocator_.deallocator(first_);first_nullptr;}myvector(constmyvectorTrhs){intsizerhs.end_-rhs.first_;first_allocator_.allocator(size);last_first_;end_first_size;T*pextrhs.first_;while(pext!rhs.last_){allocator_.construct(last_,*pext);pext;last_;}}voidoperator(constmyvectorTrhs){if(thisrhs){return;}//1.析构 2.释放内存for(T*pfirst_;p!last_;p){allocator_.destroy(p);}allocator_.deallocator(first_);intsizeend_-first_;first_allocator_.allocator(size);last_first_;end_first_size;T*pextrhs.first;while(pext!rhs.last_){allocator_.construct(last_,*pext);last_;pext;}}voidresize(){intsizeend_-first_;T*new_firstallocator_.allocator(size*2);T*new_lastnew_first;T*pextfirst_;while(pext!end_){allocator_.construct(new_last,*pext);allocator_.destroy(pext);pext;new_last;}allocator_.deallocator(first_);last_new_last;first_new_first;end_first_size*2;}voidpush_back(constTval){if(full()){resize();}allocator_.construct(last_,val);last_;}voidpop_back(){if(empty()){return;}allocator_.destroy(--last_);}