C++primer 練習13.39

來源:互聯網
上載者:User

標籤:

13.39 編寫你自己版本的StrVec,包括自己版本的reserve,capacity(參見9.4節,第318頁)和resize(參見9.3.5節,第314頁)

13.40 為你的StrVec類添加一個建構函式,它接受一個initializer_list<string>參數

 

這是StrVec.h

#pragma once#include<string>#include<memory>#include<initializer_list>using namespace std;class StrVec{public:    StrVec():        elements(nullptr),first_free(nullptr),cap(nullptr){}    StrVec(initializer_list<string> iLStr);//建構函式,接受一個initializer_list<string>參數    StrVec(const StrVec&);    StrVec& operator=(const StrVec&);    ~StrVec();    string& operator[](size_t n)const //重載下標運算子,用來實現TextQuery和QueryResult對StrVec的使用    {        return *(elements + n);    }    void push_back(const string&);    size_t size()const { return first_free - elements; }    size_t capacity()const { return cap - elements; }    string *begin()const { return elements; }    string *end()const { return first_free; }    void reserve(size_t n);//分配至少容納n個元素的空間    void resize(size_t n);//調整容器的大小為n個元素。若n<size(),則多出的元素被丟棄                          //若必須添加新元素,對新元素進行值初始化    void resize(size_t n,string str);//調整容器的大小為n個元素,任何新添加的元素都初始化為值strprivate:    allocator<string> alloc;    void chk_n_alloc()    {        if (size() == capacity())            reallocate();    }    pair<string*, string*>alloc_n_copy(const string *, const string *);    void free();    void reallocate();    string *elements;    string *first_free;    string *cap;};void StrVec::push_back(const string &s){    chk_n_alloc();    alloc.construct(first_free++, s);}pair<string*,string*>StrVec::alloc_n_copy(const string  *b, const string *e){    auto data = alloc.allocate(e - b);    return{ data,uninitialized_copy(b,e,data) };}void StrVec::free(){    if (elements) {        for (auto p = first_free;p != elements;)            alloc.destroy(--p);        alloc.deallocate(elements, cap - elements);    }}StrVec::StrVec(const StrVec &s){    auto newdata = alloc_n_copy(s.begin(), s.end());    elements = newdata.first;    first_free = cap = newdata.second;}StrVec::~StrVec() { free(); }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::reallocate(){    auto newcapacity = size() ? 2 * size() : 1;    auto newdata = alloc.allocate(newcapacity);    auto dest = newdata;    auto elem = elements;    for (size_t i = 0;i != size();++i)        alloc.construct(dest++, move(*elem++));    free();    elements = newdata;    first_free = dest;    cap = elements + newcapacity;}void StrVec::reserve(size_t n)//分配至少容納n個元素的空間{    if (n > capacity())//如果n大於capacity()才會從新分配空間    {        auto newdata = alloc.allocate(n);//重新分配n個空間,newdata為新分配的空間的首地址        auto dest = newdata;          auto elem = elements;        for (;elem != first_free;)       //為新分配的空間調用construct來實現string的構造,採用move調用的是移動建構函式            alloc.construct(dest++, move(*(elem++)));        free();                          //元素的移動完成,釋放原有的空間        elements = newdata;              //為指標賦予新的值        first_free = dest;        cap = elements + n;    }    else return;}void StrVec::resize(size_t n)//調整容器的大小為n個元素。若n<size(),則多出的元素被丟棄                      //若必須添加新元素,對新元素進行值初始化{    if (n <= size())  //如果n<size()則,應該對n後面的所有已經構造的元素調用destroy(),即多出的元素被丟棄    {        for (;first_free != elements + n;)            alloc.destroy(--first_free);    }    else    {        if (n > capacity())        {            reserve(n);   //因為n>capacity(),所以一定會分配新的空間        }        for (;first_free != elements + n;)  //添加新的元素,對新的元素進行值初始化            alloc.construct(first_free++, string(""));    }}void StrVec::resize(size_t n,string str)//調整容器的大小為n個元素,任何新添加的元素都初始化為值str                             {    if (n <= size())  //如果n<size()則,應該對n後面的所有已經構造的元素調用destroy(),即多出的元素被丟棄    {        for (;first_free != elements + n;)            alloc.destroy(--first_free);    }    else    {        if (n > capacity())        {            reserve(n);   //因為n>capacity(),所以一定會分配新的空間        }        for (;first_free != elements + n;)  //添加新的元素為str            alloc.construct(first_free++, str);    }}StrVec::StrVec(initializer_list<string> iLStr)//建構函式,接受一個initializer_list<string>參數{    auto newdata = alloc_n_copy(std::begin(iLStr), std::end(iLStr));//調用alloc_n_copy函數,返回一個pair<string*,string*>    elements = newdata.first;                            //pair的第一個元素為新分配空間的地址    first_free = cap = newdata.second;                   //pair的第二個元素為新分配空間的最後一個元素之後的地址}

下面是主函數,用來驗證程式的正確性

// 13.5.cpp : 定義控制台應用程式的進入點。//#include "stdafx.h"#define _SCL_SECURE_NO_WARNINGS#include"StrVec.h"#include<string>#include<iostream>#include<memory>using namespace std;int main(){    StrVec sv({ "li","dandan","is" });    cout << sv.size() << " " << sv.capacity() << endl;    sv.resize(5, "handsome");    cout << sv.size() << " " << sv.capacity() << endl;    sv.resize(3);    cout << sv.size() << " " << sv.capacity() << endl;    sv.resize(6);    cout << sv.size() << " " << sv.capacity() << endl;    sv.reserve(20);    sv.push_back("handsome");    cout << sv.size() << " " << sv.capacity() << endl;    return 0;}

 

C++primer 練習13.39

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.