当前位置: 代码迷 >> 综合 >> C++ class of StrVec。.实现类似STL的简单string的vector。
  详细解决方案

C++ class of StrVec。.实现类似STL的简单string的vector。

热度:17   发布时间:2023-09-29 05:26:56.0

参考c++primer中的StrVec,感觉作者代码写的很好,就记录下来。

望大家一起进步。

后续更新vector模板实现。

#include<iostream>
#include<vector>
#include<pair>
#include <string>ifdef INIT_LIST
#include<initializer_list>
#endifusing namespace std;class StrVec{
public:StrVec() : elements(nullptr), first_free(nullptr), cap(nullptr) {  }StrVec(const StrVec &);		//copy ctorStrVec &operator=(const StrVec &);#ifdef NOEXCEPTStrVec(StrVec &&) noexcept;		//copy ctorStrVec &operator=(StrVec &&) noexcept;~StrVec() noexcept;
#elseStrVec(StrVec &&) throw();StrVec &operator=(StrVec&&) throw();~StrVec() throw();
#endif#ifdef INIT_LISTStrVec(initializer_list<string>);
#elseStrVec(const string*, const string*);
#endifvoid push_back(const string &);	 //copy the elementvoid push_back(const string &&);	//move the elementvoid pop_back() { if(!is_empty()) alloc.destroy(--first_free); }size_t size() const { return first_free - elements; }size_t capacity() const { return cap - elements; }void resize(size_t n, const string &s);void resize(size_t n);void reserve(size_t n);bool is_empty() const { return first_free == elements; }// iterator interfacestring *begin() const { return elements; }string *end() const { return first_free; }string &operator[](size_t n){ return elements[n]; }const string &operator[](size_t n) const{ return elements[n]; }
private:static allocator<string> alloc;	//allocator, alloc is defined as static for the lass //utility functions:called by copy ctor, etcvoid chk_n_alloc()	{ if(capacity() == size())  reallocate();     }pair<string*, string*> alloc_n_copy(const string *, const string*);  //very importantvoid free();		//destroy elements and release memoryvoid reallocate();void reallocate(size_t newcapacity);string *elements;    // pointer to the first element in arraystring *first_free;  // pointer to the first free element in arraystring *cap;         // pointer to the one past the end of the array
};//allocate and fill unconstructor memory
inline
pair<string*, string*> 
StrVec::alloc_n_copy(const string*b, const string *e)
{auto data = alloc.allocate(e - b);// initialize and return a pair constructed from data and the value returned by// uninitialized_copyreturn {data, uninitialized_copy(b, e, data)};		
}inline
#ifdef NOEXPECT
StrVec::StrVec(StrVec &&s) noexpect
#else
StrVec::StrVec(StrVec &&s) throw()
#endif: elements(s.elements), first_free(s.first_free), cap(s.cap)
{//leave s in a state in which it is safe to run the destructors.elements = s.first_free = s.cap = nullptr;
}inline
StrVec::StrVec(const StrVec &s)
{auto newdata = alloc_n_copy(s.begin(), s.end());elements = newdata.first;first_free = cap = newdata.second;
}inline
#ifdef NOEXPECT
StrVec &StrVec::operator=(StrVec &&rhs) noexcept
#else
StrVec &StrVec::operator=(StrVec &&rhs) throw()
#endif
{// can't release left hand object before use right hand object// direct test for self-assignmentif(this != &rhs) {free();elements = rhs.elements;first_free = rhs.first_free;cap = rhs.cap;// leave rhs in a destructible staterhs.elements = rhs.first_free = rhs.cap = nullptr;}return *this;
}inline
StrVec &StrVec::operator=(const StrVec &rhs)
{auto data = alloc_n_copy(rhs.begin(), rhs.end());free();elements = data.first;first_free = cap = data.second;return *this;
}void StrVec::free()
{// may not pass deallocate at a 0 pointer; if elements is 0, there's no work to doif(elements) {for(auto p = first_free; p != elements; )alloc.destroy(--p);alloc.deallocate(elements,cap - elements);}
}
~StrVec()
{free();
}inline
void StrVec::push_back(const string &s)
{chk_n_alloc();alloc.construct(first_free++, s);
}inline
void StrVec::push_back(const string &s)
{chk_n_alloc();alloc.construct(first_free++, std::move(s));		//use move ctor of string
}inline
void StrVec::reallocate()
{auto newcapacity = size() ? 2 * size() : 1;auto newdata = alloc.allocate(newcapacity);//move old data to new dataauto dest = newdata;auto elem = elements;for(size_t i = 0; i != size(); ++i)alloc.construct(dest++, std::move(*elem++));	//will call move ctor of stringfree();		// will call dtor of stringelements = newdata;first_free = dest;cap = elements + newcapacity;
}#ifdef INIT_LIST
//ctor takes a initializer list parameter
inline
StrVec::StrVec(initializer_list<string> il)
{auto newdata = alloc_n_copy(il.begin(), il.end());elements = newdata.first;first_free = cap = newdata.second;
}
#else
inline
StrVec::StrVec(const string*b, const stringe)
{auto newdata = alloc_n_copy(b, e);elements = newdata.first;first_free = cap = newdata.second;
}
#endifvoid StrVec::reserve(size_t n)
{if(n > capacity())reallocate(n);
}inline
void StrVec::reallocate(size_t newcapacity)
{auto newdata = alloc.allocate(newcapacity);auto dest = newdata;auto elem = elements;for(size_t i = 0; i != size(); ++i)alloc.construct(dest++, std::move(*elem++));	free();		elements = newdata;first_free = dest;cap = elements + newcapacity;
}inline
void StrVec::resize(size_t n)
{if(n > size()) {while(size() < n--)push_back("");}else if(n < size()) {while(n-- < size())alloc.destroy(--first_free);	//will destroy elements but not release memory}
}inline 
void StrVec::resize(size_t n, const string &s)
{if(n > size()) {while(size() < n--)push_back(s);}
}	

 

  相关解决方案