c++ primer 习题13.39自己做的答案
生活随笔
收集整理的這篇文章主要介紹了
c++ primer 习题13.39自己做的答案
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
//strvec.cc#include <string>
#include <iostream>
#include <memory>
#include "strvec.h"
using namespace std;//一個類對象是const的,它的元素不是const的
StrVec::StrVec(const StrVec &rhs)
{
//allocate_n_copy:可以開辟新的存儲空間,然后把給定參數范圍的元素逐個拷貝進去,然后
//返回構造好的空間的首元素地址和尾后元素的地址
pair<string*, string*> data = allocate_n_copy(rhs.elements,rhs.first_free);
elements = data.first;
first_free = cap = data.second;
}
StrVec& StrVec::operator=(const StrVec & rhs)
{auto data = allocate_n_copy(rhs.begin(),rhs.end());free(); //拷貝賦值運算符比拷貝構造函數多一個釋放左側對象的空間的函數elements = data.first;first_free = cap = data.second;return *this;
}
size_t StrVec::capacity()const
{return cap - elements;
}
size_t StrVec::size()const
{return first_free - elements;
}void StrVec::free()
{
if(elements){for(string * p = first_free; p != elements;){alloc.destroy(-- p); }alloc.deallocate(elements,cap - elements); //cap -elements 可以計算一共有多少空間}
}void StrVec::chk_n_alloc()
{
//如果容器已滿,那么重新分配
if(size() == capacity())reallocate();
}pair<string*,string*> StrVec::allocate_n_copy(const string* b,const string * e)
{string * const data = alloc.allocate(e - b);return {data,uninitialized_copy(b,e,data)};}
allocator<string> StrVec::alloc;void StrVec::reallocate_1()
{
size_t new_capacity = size() ? 1 : 2 * size();
auto new_elements = alloc.allocate(new_capacity);
auto new_first_free = uninitialized_copy(elements,first_free,new_elements);
free();
auto new_cap = new_elements + new_capacity;
elements = new_elements;
first_free = new_first_free;
cap = new_cap;
}void StrVec::reallocate()
{auto new_capacity = size() ? 2*size() : 1;
auto new_elements = alloc.allocate(new_capacity);
auto dest = new_elements;
auto elem = elements;
for(int i = 0; i != size() ; ++ i)
{//std::move(),在需要構造的地方也是可以使用的 alloc.construct(dest ++,std::move(*elem++));
}
free();
elements = new_elements;
first_free = dest;
cap = new_elements + new_capacity;}void StrVec::push_back(const string & rhs)
{chk_n_alloc(); //確保有空間容納新元素alloc.construct(first_free ++,10,'c');}void StrVec::pop_back()
{alloc.destroy(first_free --);
}StrVec::~StrVec()
{free();
}string * StrVec::begin()const
{return elements;
}
string * StrVec::end()const
{return first_free;
}void StrVec::reserve(size_t s)
{
if(s <= size()) return ;//先移動元素,然后再釋放左側對象空間
auto const new_elements = alloc.allocate(s);
auto dest = new_elements;
auto elem = elements;
for(size_t i = 0; i != size();++ i ) {alloc.construct(dest ++, std::move(*elem ++));}
free();
elements = new_elements;
cap = new_elements + s;
first_free = dest;}void StrVec::resize(size_t t)
{
if(t > capacity())return ; else if(t < size()){auto new_first_free = first_free;for(size_t i = 0; i != size() - t; ++ i){alloc.destroy(-- new_first_free);}first_free = new_first_free;return;}
else if(t == size()){return ;}
else if(t > size()){auto new_first_free = first_free;for(size_t i = 0;i != t - size() ; ++ i){alloc.construct(new_first_free ++,""); } first_free = new_first_free; return;}
}void StrVec::print_info()const
{
cout << "capacity:" << capacity() << endl;
cout << "size:" <<size()<< endl;
}
文件main.cc
#include <string> #include <iostream> #include <memory> #include "strvec.h" using namespace std; int main() { StrVec v; //cout << v.capacity() << endl; //cout << v.size() << endl;for(int i = 0;i != 10; ++i){v.push_back(string("abcde"));cout << v.size() << endl;} cout <<"capacity:" << v.capacity() << endl; cout <<"size:" << v.size() << endl;for(string * p = v.begin(); p != v.end(); ++p)cout << *p << endl; v.print_info();v.resize(5); v.resize(5); v.resize(100); cout << "big" << endl; v.print_info(); v.reserve(100); v.print_info(); cout << "after resize: " << endl; for(string* p = v.begin(); p != v.end(); ++ p)cout << *p << endl; v.print_info();return 0; } //strvec.h #include <string> #include <iostream> #include <memory> using namespace std; class StrVec {public:StrVec(): //allocator成員進行默認初始化elements(nullptr),first_free(nullptr),cap(nullptr){}StrVec(const StrVec &); //拷貝構造函數StrVec& operator=(const StrVec &);~StrVec();void push_back(const string &);void pop_back();size_t size()const;size_t capacity()const;string *begin()const;string *end()const;//習題13.39void resize(size_t );void reserve(size_t );void shrink_to_fit();void print_info()const;private:static allocator<string> alloc;string *elements; //指向指向數組首元素的指針string *first_free; //指向第一個空閑元素的指針string *cap; //指向數組尾后位置的指針void free(); //銷毀元素并且釋放內存void reallocate_1(); 獲得更多內存并拷貝已有元素void reallocate();pair<string*,string*> allocate_n_copy(const string*,const string*);//開辟空間,拷貝給定范圍的元素void chk_n_alloc();};運行結果:?
1 2 3 4 5 6 7 8 9 10 capacity:16 size:10 cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc capacity:16 size:10 big capacity:16 size:5 capacity:100 size:5 after resize: cccccccccc cccccccccc cccccccccc cccccccccc cccccccccc capacity:100 size:5strvec.h中雖然申明了shrink_to_fit,但是這個函數目前實現不了,因為allocator對象分配的空間,目前不能釋放一部分;因為釋放allocator對象分配的空間需要函數deallocate函數,這個函數形如:
deallocate(p,n);其中p必須是先前調用allocate得到的指針,而且n必須是先前調用allocate時候的空間的大小。
所以只能全部釋放呀。不能部分釋放。所以shrink_to_fit是不能實現的。
習題13.40自編答案
StrVec::StrVec(initializer_list<string> li) { //迭代器可以直接給指針賦值,棒呀,都什么情況可以這樣操作呢? auto data = allocate_n_copy(li.begin(),li.end()); elements = data.first; first_free = cap = data.second; }練習13.42
總結
以上是生活随笔為你收集整理的c++ primer 习题13.39自己做的答案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: hplaserjet1022老提示打印错
- 下一篇: c++primer练习13.42