C++primer5th模拟vector之StrVec类

出现的问题:书中alloc为static,编译时连接错误,不使用static可正常运行。因为在c++11中,static必须要初始化
//现有知识储备不知道怎么给alloc初始化,所以……暂时去掉static

StrVec.h头文件内容为

#pragma once
#ifndef STRVEC_H
#define STRVEC_H
#include<string>
#include<memory>
#include<utility>//move
#include<initializer_list>
using std::string;
using std::pair;
using std::allocator;
using std::initializer_list;
//成员elements, first_free,cap----工具函数:alloc_n_copy, free, chk_n_alloc, reallocate

class StrVec {
public:
    StrVec() :elements(nullptr), first_free(nullptr), cap(nullptr) {}//默认构造函数
    StrVec(initializer_list<string> v1);
    StrVec(const StrVec&);//拷贝构造函数
    StrVec::StrVec(StrVec &&s) noexcept:elements(s.elements), first_free(s.first_free), cap(s.cap) 
    { s.elements = s.cap = s.first_free = nullptr; }//移动构造函数
    StrVec& operator = (const StrVec&);//拷贝赋值运算符
    StrVec& operator = (StrVec &&s);//移动赋值运算符
    ~StrVec() { free(); }//析构

    void push_back(const string&);
    size_t size() { return first_free - elements; }
    size_t capacity() { return cap - elements; }
    string* begin() const { return elements; }
    string* end() const { return first_free; }
    size_t capacity() const { return cap - elements; }
    void reserve(size_t);
    void resize(size_t n);
    void resize(size_t n, const string &s);
private:
    allocator<string> alloc;//alloc用来分配内存
    pair<string*, string*> alloc_n_copy(const string*, const string*);
    void chk_n_alloc() { if (size() == capacity()) reallocate(); }
    void free();
    void reallocate();
    void reallocate(size_t);
    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()
{
//用lambda表达式的版本
//  for_each(elements, first_free, [](string &s) {alloc.destroy(&s); });//此语句要求alloc为static类型
    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::operator = (const StrVec &s)
{
    auto data = alloc_n_copy(s.begin(), s.end());
    free();//干掉左侧的
    elements = data.first;
    first_free = cap = data.second;
    return *this;
}
StrVec& StrVec::operator = (StrVec &&s)
{
    if (this != &s) {
        free();
        elements = s.elements;
        first_free = s.first_free;
        cap = s.cap;
        s.elements = s.first_free = s.cap = nullptr;
    }
    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++, std::move(*elem++));//调用move表示希望用 string的移动构造函数
    free();//移动完元素后释放旧内存
    //
    elements = newdata;
    first_free = dest;
    cap = elements + newcapacity;
}
//
void StrVec::reallocate()
{
    auto newcapacity = size() ? 2 * size() : 1;
    auto first = alloc.allocate(newcapacity);
    //移动构造,uninitialized_copy 调用 construct将元素 移动构造
    auto last = uninitialized_copy(make_move_iterator(begin()), make_move_iterator(end()), first);
    free();
    elements = first;
    first_free = last;
    cap = elements + newcapacity;
}
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;
}
StrVec::StrVec(initializer_list<string> v1)
{
    auto newdata = alloc_n_copy(v1.begin(), v1.end());
    elements = newdata.first;
    first_free = cap = newdata.second;
}
void StrVec::reserve(size_t t)
{
    if (t > capacity())
        reallocate(t);
}
void StrVec::resize(size_t n)
{
    if (n > size())
        while (size() < n)
            push_back("");
    else if (n < size()) {
        while (size() > n)
            alloc.destroy(--first_free);
    }
}
void StrVec::resize(size_t n, const string &s)
{
    if (n > size()) {
        while (size() < n)
            push_back(s);
    }
}
#endif // !STRVEC_H

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: "C Primer 5th"是由Stanley B. Lippman、Josee Lajoie和Barbara E. Moo合著的一本经典的计算机编程教材。本书是一本C语言入门教程,适合想学习C语言的初学者使用。该教材已经成为许多大学计算机科学专业的必读教材。 "C Primer 5th"以清晰的语言和简单的编程示例来引导读者逐步学习C语言的基本概念和技巧。它从最基础的C语言语法和变量开始,然后逐渐介绍更高级的主题,如数组、指针、结构体、函数和文件操作等。 值得一提的是,本书在教授C语言的同时,也不忽略了现代编程实践和技术。它包含了C99和C11标准的新特性和改进,以及对C语言在实际编程中的应用的详细讨论。 此外,本书还提供了大量的练习题和编程挑战,帮助读者巩固所学知识,并提供了答案和解释供参考。这些练习题以及书中的代码示例都有助于读者理解如何将C语言应用于实际项目开发中。 总之,《C Primer 5th》是一本优秀的C语言教材,适合初学者入门。它以清晰易懂的语言、实用的示例和丰富的练习题,帮助读者逐步掌握C语言编程的基本技能和实践经验。无论是想要学习编程基础知识的初学者,还是希望进一步提升C语言编程技能的经验丰富者,都能从这本书中获益良多。 ### 回答2: 《C Primer第五版》是一本非常流行的编程入门教材,也是学习C语言的经典教材之一。本书详细介绍了C语言的基本概念和语法规则,让读者快速入门并掌握C语言编程。 这本书的英文高清版指的是书籍中提供了高质量的英文文本和印刷质量。高清版通常在图书印刷质量方面有更高的标准,印刷清晰度更高,图文排版更精美。对于学习者来说,高清版可以更清晰地看到代码和示例,并更好地理解教材。 《C Primer第五版》是一本非常实用的书籍,里面包含了大量的示例和练习题,帮助读者巩固所学知识。通过学习本书,读者可以了解C语言的基本语法、数组、指针、结构体、函数等内容,并能够编写简单的C程序。 此外,本书还介绍了一些常用的C库函数和标准库,如字符串处理函数和数学函数等,方便读者快速应用到实际的编程项目中。 总的来说,如果你想学习C语言编程,尤其是作为初学者,那么《C Primer第五版》是一本非常值得推荐的书籍。无论是英文高清版还是其他版本,都能为你提供清晰易懂的教材内容,帮助你快速入门并掌握C语言编程。 ### 回答3: 《C Primer Plus》是一本经典的C语言编程入门书籍,目前最新的版本是第五版。这本书以简洁明了的风格,深入浅出地介绍了C语言的基本概念和编程技术。 《C Primer Plus》第五版的英文高清版,是指该书的英语原版的高清电子版本。高清版的出现,使读者可以更清晰地阅读书中的文字和代码示例, 更加方便地学习和理解编程知识。 该书按照逻辑清晰地从基本的C语言语法开始,分步骤地引导读者进入编程的世界。它从简单的概念和例子开始,逐渐引入更复杂的编程技术,包括数组、函数、指针、结构体、文件操作等。每个概念都有相应的代码示例和练习题,读者可以通过实践巩固所学知识。 此外,该书还涵盖了一些常见的编程技巧和建议,帮助读者养成良好的编程习惯。它也介绍了一些C语言的高级特性,如内存管理、位运算、预处理器等。这些内容不仅适用于初学者,也对有一定编程经验的读者有所裨益。 总体而言,《C Primer Plus》第五版的英文高清版是一本全面且易于理解的C语言入门书籍。通过系统地学习该书,读者将获得扎实的编程基础,为进一步学习和应用C语言打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值