c++ primer 16.1.2节练习 实现泛型vector

在这里插入图片描述
StrVec可以看我之前写个。

因为写完本篇程序发现个奇怪的问题,程序用vec就没事,用vec就炸,排查了一下又是越界问题。这里吹一下vs,debug功能好强啊,因为string释放时会调用析构,导致free函数释放时多释放了一个空的指针。但基础类型销毁的时候没有析构函数所以没事。

完整代码

#include <iostream>
#include<string>
#include<vector>
#include<list>
#include<memory>

template <typename elemType> class vec {
public:
    vec() :elements(nullptr), first_free(nullptr), cap(nullptr) {}
    vec(std::initializer_list<elemType>);
    vec(const vec&);
    vec& operator=(const vec<elemType>&);
    ~vec(); 

    void push_back(const elemType&);
    size_t size() const { return first_free - elements; }
    size_t capacity() const { return cap - elements; }
    size_t reserve(size_t);
    //size_t resize(size_t);
    
    elemType* begin() const { return elements; }
    elemType* end() const { return first_free; }

    void print_message(); //bebug



private:
    std::allocator<elemType> alloc ;
    void chk_n_alloc();
    std::pair<elemType*, elemType*> alloc_n_copy(const elemType*, const elemType*);
    void free();
    void reallocate();

    elemType* elements;  //第一个元素
    elemType* first_free; //最后一个元素的后一个
    elemType* cap;         //最后一个空间
};
template <typename elemType>
void vec<elemType>::chk_n_alloc() {
    if (size() == capacity())
        reallocate();
}
template <typename elemType>
void vec<elemType>::free(){
    if (elements) {
        for (auto p = first_free; p != elements; p--) 
            alloc.destroy(--p);
        alloc.deallocate(elements, cap - elements);
    }
}
template <typename elemType>
void vec<elemType>::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));
    free();
    elements = newdata;
    first_free = dest;
    cap = elements + newcapacity;
}
template <typename elemType>
vec<elemType>::vec(std::initializer_list<elemType> s) {
    reserve(2 * s.size());
    auto dest = elements;
    for (auto i : s)
        alloc.construct(dest++, i);
    first_free = dest;
}
template <typename elemType>
std::pair<elemType*, elemType*> vec<elemType>::alloc_n_copy(const elemType* b, const elemType* e) {
    auto data = alloc.allocate(e - b);
    return { data,std::uninitialized_copy(b,e,data) };
}
template <typename elemType>
vec<elemType>::vec(const vec& s) {
    auto newdata = alloc_n_copy(s.begin(), s.end());
    elements = newdata.first;
    first_free = newdata.second;
}
template <typename elemType>
vec<elemType>::~vec() {
    free();
}
template <typename elemType>
vec<elemType>& vec<elemType>::operator=(const vec<elemType> &s) {
    auto data = alloc_n_copy(s.begin(), s.end());
    free();
    elements = data.first;
    first_free = cap = data.second;
    return *this;
}
template <typename elemType>
void vec<elemType>::push_back(const elemType& n) {
    chk_n_alloc();
    alloc.construct(first_free++, n);
    
}
template <typename elemType>
void vec<elemType>::print_message() {
    for (auto i = begin(); i != end(); ++i)
        std::cout << *i << " ";
}
template <typename elemType>
size_t vec<elemType>::reserve(size_t n) {
    auto newcapacity = n;
    auto old_size = size();
    if (newcapacity < old_size)
        old_size = n;
    auto newdata = alloc.allocate(newcapacity);
    auto dest = newdata;
    auto elem = elements;
    for (size_t i = 0; i != old_size; ++i)
        alloc.construct(dest++, std::move(*elem++));
    free();
    elements = newdata;
    first_free = dest;
    cap = elements + newcapacity;
    return cap - elements;

}
int main() {
    
    vec<std::string> s = { "a","v","c" };
    s.push_back("f");
    vec<int> t = { 1,2,3,4 };
    t.push_back(5);
    s.print_message();
    t.print_message();
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值