您的位置:首页 > 编程语言 > C语言/C++

C++ Primer 13.5节练习

2016-04-13 20:32 721 查看
--------------------------------------------------StrVec.h-------------------------------------------------------
#ifndef STRVEC_H
#define STRVEC_H
#define _SCL_SECURE_NO_WARNINGS

#include <iostream>
#include <string>
#include <memory>
#include <initializer_list>

using namespace std;

class StrVec{
public:
StrVec() :elements(nullptr), first_free(nullptr), cap(nullptr) {}
StrVec(const initializer_list<string>&);
StrVec(const StrVec&);
StrVec& operator=(const StrVec&);
~StrVec();
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);
void resize(size_t n, const string &str);
void printf();
private:
static allocator<string> alloc;
string *elements;
string *first_free;
string *cap;
void check_n_alloc() { if (size() == capacity()) reallocate(); }
void reallocate();
void free();
pair<string*, string*> alloc_n_copy(const string*, const string*);
};
#endif
--------------------------------------------------StrVec.cpp-------------------------------------------------------
#include "StrVec.h"

allocator<string> StrVec::alloc;

void StrVec::push_back(const string &str){
check_n_alloc();
alloc.construct(first_free++, str);
}

pair<string*, string*> StrVec::alloc_n_copy(const string *b, const string *e){
auto data = alloc.allocate(e - b);
auto next_ptr = uninitialized_copy(b,e,data);
return{ data, next_ptr };
}

void StrVec::free(){
if (elements){
for (auto be = elements; be != first_free; ++be)
alloc.destroy(be);
alloc.deallocate(elements,capacity());
}
}

StrVec::StrVec(const StrVec &s){
auto newdata = alloc_n_copy(s.elements, s.first_free);
elements = newdata.first;
first_free = cap = newdata.second;
}

StrVec::~StrVec(){
free();
}

StrVec& StrVec::operator=(const StrVec &s){
auto newdata = alloc_n_copy(s.elements, s.first_free);
free();
elements = newdata.first;
first_free = cap = newdata.second;
return *this;
}

StrVec::StrVec(const initializer_list<string> &lis1){
elements = alloc.allocate(lis1.end() - lis1.begin());
cap = first_free = uninitialized_copy(lis1.begin(), lis1.end(), elements);
}

void StrVec::reallocate(){
auto newcapacity = size() ? 2 * size() : 1;
auto const newdata = alloc.allocate(newcapacity);
auto p = newdata;
auto p_ele = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(p++, move(*p_ele++));
free();
elements = newdata;
first_free = p;
cap = elements + newcapacity;
}

void StrVec::reserve(size_t n){
if (n>capacity()){
auto newdata = alloc.allocate(n);
auto p = newdata;
auto p_ele = elements;
for (size_t i = 0; i != size(); ++i)
alloc.construct(p++, move(*p_ele++));
free();
elements = newdata;
first_free = p;
cap = elements + n;
}
}

void StrVec::resize(size_t n, const string &str = string()){
if (n <= capacity()){
if (n < size()){
for (auto i = elements + n; i != first_free; ++i)
alloc.destroy(i);
first_free = elements + n;
}
else{
for (auto i = first_free; i != first_free + n - size(); ++i)
alloc.construct(i, str);
first_free = elements + n;
}
}
}

void StrVec::printf(){
for (auto i = elements; i != first_free; ++i)
cout << *i << " ";
}
--------------------------------------------------main.cpp-------------------------------------------------------
#include "StrVec.h"

int main(){
initializer_list<string> lis1{ "how", "are", "you"};
StrVec s1, s2(lis1),s3(s2),s4=s3;
s1 = s2;
s1.printf();
cout << endl;
s2.printf();
cout << endl;
s3.printf();
cout << endl;
s4.printf();
cout << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "size: " << s2.size() << endl;

cout << endl;
s2.push_back("push_insert");
s2.printf();
cout << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "size: " << s2.size() << endl;

cout << endl;
s2.reserve(10);
s2.resize(3, "not_insert");
s2.printf();
cout << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "size: " << s2.size() << endl;

cout << endl;
s2.resize(6, "must_insert");
s2.printf();
cout << endl;
cout << "capacity: " << s2.capacity() << endl;
cout << "size: " << s2.size() << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ Primer 练习 答案