首页 > 编程语言 >C++ //练习 16.16 将StrVec类(参见13.5节,第465页)重写为模板,命名为Vec。

C++ //练习 16.16 将StrVec类(参见13.5节,第465页)重写为模板,命名为Vec。

时间:2024-08-04 08:55:30浏览次数:18  
标签:alloc elements 465 first free Vec size C++

C++ Primer(第5版) 练习 16.16

练习 16.16 将StrVec类(参见13.5节,第465页)重写为模板,命名为Vec。

环境:Linux Ubuntu(云服务器)
工具:vim

 

代码块
#include<iostream>
#include<memory>
#include<utility>
using namespace std;

template <typename T> class Vec{
	
    public:
    Vec(): elements(nullptr), first_free(nullptr), cap(nullptr) {}
    Vec(const Vec &);
    Vec &operator= (const Vec &);
    ~Vec();
    void push_back(const T &);
    size_t size() const { return first_free - elements; } 
    size_t capacity() const { return cap - elements; }
    T *begin() const { return elements; }
    T *end() const { return first_free; }
    void reserve(std::size_t s);
    void resize(std::size_t s);

    private:
    Static std::allocator<T> alloc;
    void chk_n_alloc(){ if (size() == capacity()) reallocate(); }
    std::pair<T*, T*>alloc_n_copy(const T*, const T*);
    void free();
    void reallocate();
    T *elements;
    T *first_free;
    T *cap;
};

template <typename T>
void Vec<T>::push_back(const T &s){
    chk_n_alloc();
    alloc.construct(first_free++, s);
}

template <typename T>
std::pair<T*, T*> Vec<T>::alloc_n_copy(const T *b, const T *e){
    auto data = alloc.allocate(e - b);
    return {data, uninitialized_copy(b, e, data)};
}

template <typename T>
void Vec<T>:free(){
    if(elements){
        for(auto p = first_free; p != elements; ){
            alloc.destroy(--p);

        }
        alloc.deallocate(elements, cap - elements);
    }
}

template <typename T>
Vec<T>::Vec(const Vec &s){
    auto newdata = alloc_n_copy(s.begin(), s.end());
    elements = newdata.first;
    first_free = cap = newdata.second;
}

template <typename T>
Vec<T>::~Vec() { free(); }

template <typename T>
Vec<T> &Vec<T>::operator= (const Vec &rhs){
    auto data = alloc_n_copy(rhs.begin(), rhs.end());
    free();
    elements = data.first;
    first_free = cap = data.second;
    return *this;
}

template <typename T>
void Vec<T>::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;
}

template <typename T>
void Vec<T>::reserve(std::size_t s){
	if(s <= size()){
	 	return;
	}
	auto newElem = alloc.allocate(s);
	auto dest = newElem;
	auto elem = elements;
	for(size_t i = 0; i != size(); ++i){
		alloc.construct(dest++, move(*elem++));
	}
	free();
	elements = newElem;
	cap = newElem + s;
	first_free = dest;
}

template <typename T>
void Vec<T>::resize(std::size_t s){
	if(s > capacity()){
		return ;
	}
	if(s < size()){
		auto newFisrt = first_free;
		for(size_t i = 0; i != size() - s; ++i){
			alloc.destroy(--newFirst);
		}
		fisrt_free = newFirst;
		return ;
	}
	else if(s == size()){
		return ;
	}
	else{
		auto newFirst = first_free;
		for(size_t i = 0; i != s - size(); ++i){
			alloc.construct(newFirst++, "");
		}
		first_free = newFirst;
		return ;
	}
}

标签:alloc,elements,465,first,free,Vec,size,C++
From: https://blog.csdn.net/navicheung/article/details/140837380

相关文章

  • 【C++】多态 - 含3个案例
    目录一、多态分类二、多态区别三、多态基本语法四、多态原理五、案例1:计算机类六、纯虚函数和抽象类七、案例2:制作饮品八、虚析构和纯虚析构九、案例3:电脑组装需求分析及实现多态是C++面向对象三大特性之一一、多态分类①静态多态:函数重载、运算符重载、复用函......
  • C++__位运算符:异或运算符 ^
    目的:     了解异或运算符的定义、性质及用法。定义:    二元运算符,符号为^,与位与、位或不同的是,它在二进制中为相同为0,不同为1。而且它还满足这几种运算规则:        1、任何数^0都等于它本身;    2、两个相同的数异或结果为0;    ......
  • C++自定义接口类设计器之模板代码生成四
    关键代码QStringListmultis=templateStr.split('\n');boolstartConfig=false;boolstartVar=false;boolstartTemplate=false;for(constauto&line:multis){if(startConfig){if(line.trimmed().st......
  • c++__位运算符:位与运算符&
    目的:了解位与运算符并加深对它的运用定义:一种二元运算符,符号为&,运用于二进制数中,特性为有0为0。#include<iostream>usingnamespacestd;intmain(){inta=0b1010;//10intb=0b0110;//6//a&b=0b0010;2cout<<(a&b)<<endl;}应用:1、判断奇偶性......
  • C++实现静态链表
    #include<iostream>usingnamespacestd;//定义静态链表的最大容量constintMAX_SIZE=100;//节点类classNode{public:intdata;//节点存储的数据intnext;//节点指向下一个节点的索引(在数组中的位置)//默认构造函数Node():data(0......
  • c++三国杀
    废话不多说,直接上代码!!!#include<iostream>#include<time.h>#include<stdio.h>#include<stdlib.h>usingnamespacestd;structpai{intpaifu;inthuase;intyanse;intdianshu;intleixing;intchangdu;voidKanpai(){if(paifu==0||paifu==......
  • 「字符串」实现Trie(字典树|前缀树)的功能 / 手撕数据结构(C++)
    概述在浏览器搜索栏里输入几个字,就弹出了以你的输入为开头的一系列句子。浏览器是怎么知道你接下来要输什么的?来看看字典树干了什么。字典树是一种高效记录字符串和查找字符串的数据结构。它以每个字符作为一个节点对字符串进行分割记录,节点形成树状结构,在录入或查找时只......
  • 【leetcode详解】正方形中的最多点数【中等】(C++思路精析)
    思路精析:自定义结构体解读:一个点是否在题给正方形中,只取决于其横纵坐标的最大值,记为dis沟通二位数组points和字符串s的桥梁,就是这个点的序号,记为idx由此自定义结构体,储存dis和idx//其中booloperator部分的功能:重载小于操作符“<”,使sort(vc.begin(),vc.end());按dis......
  • 整数二分(c++)
    1、什么是整数二分:即可以看做成找数字那个游戏在一百个数字中找到指定的数字(66)A出题B:50A50太小了B:(50+100)/2=75A75太大了B:(50+75)/2=62…所以也可以知道一个结论:有单调性,一定可以二分。可以二分的题目,不一定有单调性。2、代码思路:1、寻找到满足......
  • 【C++BFS】802. 找到最终的安全状态
    本文涉及知识点C++BFS算法LeetCode802.找到最终的安全状态有一个有n个节点的有向图,节点按0到n-1编号。图由一个索引从0开始的2D整数数组graph表示,graph[i]是与节点i相邻的节点的整数数组,这意味着从节点i到graph[i]中的每个节点都有一条边。如果一......