c++理解(三)

        本文主要探讨c++相关知识。

模板是对类型参数化
函数模板特化不是模板函数重载
allocator(空间配置器):内存开辟释放,对象构造析构
优先调用对象成员方法实现的运算符重载函数,其次全局作用域找
迭代器遍历访问元素,调用erase,insert方法后,当前位置到容器末尾元素的所有迭代器全部失效
malloc只开辟空间,new还可初始化
malloc开辟内存失败返回nullptr,new(malloc实现)抛出bad_alloc异常
delete(free实现)先调析构函数再free,无析构函数delete和free相同
new和delete也是函数重载符调用
除了对象的其他类型变量的数组和单个变量可混用delete/delete []
对象在new开辟内存时会多开辟4字节来存储对象个数,使用delete []时才可正确调用析构函数
对象池:短时间内多次使用用一块内存(new/delete)

demo1:

        vector实现

结构图:

 run.sh

#!/bin/bash
 
if [ -f ./Makefile ]
then
        make clean
fi
 
cmake .
 
make
 
echo "---------------------------------"
 
./pro

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.28)                            #最低版本要求
 
SET(CMAKE_CXX_COMPILER "g++-11")                                #设置g++编译器
 
PROJECT(CLASS)                                                  #设置工程名
 
MESSAGE(STATUS "CPP test")                                      #打印消息
 
ADD_EXECUTABLE(pro test.cpp)                                    #生成可执行文件

clean.sh

rm -rf CMakeCache.txt CMakeFiles Makefile cmake_install.cmake *.o pro

test.cpp

#include <iostream>

//空间配置器
template<typename T>
struct Allocator
{
        //开辟空间
        T* Allocate(size_t size)
        {
                return (T*)malloc(sizeof(T) * size);
        }

        //释放空间
        void des_Allocate(void *p)
        {
                free(p);
        }

        //构造元素
        void construct(T *p,const T& value)
        {
                new (p) T(value);
        }

        //释放元素
        void des_construct(T *p)
        {
                p->~T();
        }
};

template<typename T,typename Alloc = Allocator<T>>
class vector
{
        public:
                vector(int size = 5)
                {
                        first = allocator.Allocate(size);
                        last = first;
                        end = first + size;
                }

                ~vector()
                {
                        for(T *p = first; p != last; p++)
                        {
                                allocator.des_construct(p);
                        }

                        allocator.des_Allocate(first);
                        first = last = end = nullptr;
                }

                vector(const vector<T> &rhs)
                {
                        first = allocator.Allocate(rhs.end - rhs.first);
                        last = first + (rhs.last - rhs.first );
                        end = first + (rhs.end - rhs.first);

                        for(T *p = first; p != last; p++)
                        {
                                allocator.construct(p,*(rhs.first + (p - first)));
                        }
                }

                vector &operator=(const vector<T> &rhs)
                {
                        if(this == &rhs)
                                return *this;

                        delete [] first;
                        first = allocator.Allocate(rhs.end - rhs.first);
                        last = first + (rhs.last - rhs.first );
                        end = first + (rhs.end - rhs.first);

                        for(T *p = first; p != last -1; p++)
                        {
                                allocator.construct(p,*(rhs.first + (p - first)));
                        }
                }

                void push_back(const T& value)
                {
                        if(full())
                                expand();
                        allocator.construct(last,value);
                        last++;
                }

                void pop_back()
                {
                        if(empty())
                                return;
                        allocator.des_construct(last);
                        last--;
                }

                T front() const
                {
                        return *first;
                }

                T back() const
                {
                        return *(last - 1);
                }

                bool full() const 
                {
                        return last  == end;
                }

                bool empty() const
                {
                        return first == last;
                }

                T* data() const
                {
                        return first;
                }

                size_t size() const
                {
                        return (last - first);
                }

                T &operator[](unsigned int index) const
                {
                        if(index > size())
                                throw "out of range";
                        return first[index];
                }

                T &at(unsigned int index)
                {
                        if(index > size())
                                throw "out of range";
                        return first[index];
                }

                size_t capacity() const
                {
                        return (end - first);
                }

                //迭代器
                class iterator
                {
                        public:
                                friend class vector<T,Alloc>;
                                iterator(vector<T,Alloc> *pvec = nullptr,T *ptr = nullptr)
                                        :pvec(pvec),ptr(ptr)
                                {
                                        Iterator_Base *itb = new Iterator_Base(this,pvec->head.next);
                                        pvec->head.next = itb;
                                };

                                T &operator*() const
                                {
                                        if(pvec == nullptr)
                                                throw "iterator invaild";
                                        return *ptr;
                                }

                                T *operator->() const
                                {
                                        if(pvec == nullptr)
                                                throw "iterator invaild";
                                        return ptr;
                                }

                                T *operator++() 
                                {
                                        if(pvec == nullptr)
                                                throw "iterator invaild"; 
                                        return ++ptr;
                                }

                                T *operator++(int) 
                                {
                                        if(pvec == nullptr)
                                                throw "iterator invaild";
                                        return ptr++;
                                }

                                T *operator--()
                                {
                                        if(pvec == nullptr)
                                                throw "iterator invaild";
                                        return --ptr;
                                }

                                T *operator--(int)
                                {
                                        if(pvec == nullptr)
                                                throw "iterator invaild";
                                        return ptr--;
                                }

                                bool operator==(const iterator &it)
                                {
                                        //迭代器为空,两个不同迭代器
                                        if(pvec == nullptr || pvec != it.pvec)
                                                throw "iterator incompatable";
                                        return ptr == it.ptr;
                                }

                                bool operator!=(const iterator &it) const
                                {
                                        //迭代器为空,两个不同迭代器
                                        if(pvec == nullptr || pvec != it.pvec)
                                                throw "iterator incompatable";
                                        return ptr != it.ptr;
                                }

                        private:
                                T* ptr;
                                vector<T,Alloc> *pvec;
                };

                //头迭代器
                iterator ibegin()
                {
                        return iterator(this,first);
                }

                //尾迭代器
                iterator iend()
                {
                        return iterator(this,last);
                }

                //迭代器失效,释放元素资源
                void iterator_clear(T *first,T *last)
                {
                        Iterator_Base *pre = &(this->head);
                        Iterator_Base *it = this->head.next;
                        while(it != nullptr)
                        {
                                if(it->cur->ptr > first && it->cur->ptr <= last)
                                {
                                        it->cur->pvec = nullptr;
                                        pre->next = it->next;
                                        delete it;
                                        it = pre->next;
                                }
                                else
                                {
                                        pre = it;
                                        it = it ->next;
                                }
                        }
                }

                //元素插入方法,迭代器失效
                iterator insert(iterator it, const T &val)
                {
                        iterator_clear(it.ptr - 1,last);
                        T *p = last;
                        while (p > it.ptr)
                        {
                                allocator.construct(p, *(p-1));
                                allocator.des_construct(p - 1);
                                p--;
                        }
                        allocator.construct(p, val);
                        last++;
                        return iterator(this, p);
                }

                //元素擦除方法,迭代器失效
                iterator erase(iterator it)
                {
                        iterator_clear(it.ptr - 1,last);
                        T *p = it.ptr;
                        while (p < last-1)
                        {
                                allocator.des_construct(p);
                                allocator.construct(p, *(p+1));
                                p++;
                        }
                        allocator.des_construct(p);
                        last--;
                        return iterator(this, it.ptr);
                }


        private:
                T *first;
                T *last;
                T *end;
                Alloc allocator;

                //迭代器指针,迭代器失效释放资源和重构迭代器
                struct Iterator_Base
                {
                        Iterator_Base(iterator *c = nullptr,Iterator_Base *next = nullptr)
                                :cur(c),
                                next(next){};

                        iterator *cur;
                        Iterator_Base *next;
                };
                Iterator_Base head;

                //扩容方法
                void expand()
                {
                        int size = end - first;
                        T* tmp = allocator.Allocate(2 * size);
                        for(int i = 0;i < size;i++)
                        {
                                allocator.construct(tmp + i,*(first + i));
                                allocator.des_construct(first + i);
                        }
                        allocator.des_Allocate(first);

                        first = tmp;
                        last = tmp + size;
                        end = tmp + (2 * size);
                }

};

class Test
{
        public:
                Test(){};
                Test(int num):num(num){};
                int num;
};

int main()
{
        Test t1(1),t2(2),t3(3),t4(4),t5(5),t6(6);
        vector<Test> v;
        v.push_back(t1);
        v.push_back(t2);
        v.push_back(t3);
        v.push_back(t4);
        v.push_back(t5);
        v.push_back(t6);
        vector<Test> v1(v);
        vector<Test> v2 = v1;
        vector<Test> v3 = v1;
        std::cout << "front():" << v2.front().num << std::endl;
        std::cout << "back():" << v2.back().num << std::endl;
        std::cout << "data():" << v2.data()->num << std::endl;
        std::cout << "size():" << v2.size() << std::endl;
        std::cout << "[]:" << v2[1].num << std::endl;
        std::cout << "at():" << v2.at(1).num << std::endl;
        std::cout << "capacity():" << v2.capacity() << std::endl;
        v2.pop_back();
        v2.pop_back();
        v2.pop_back();
        v2.pop_back();
        v2.pop_back();
        v2.pop_back();
        std::cout << "v:";
        for(auto it = v.ibegin();it != v.iend();it++)
        {
                std::cout << it->num << " ";
        }
        std::cout << std::endl;
        for(auto it = v.ibegin();it != v.iend();it++)
        {
                if(it->num == 2)
                {
                        it = v.insert(it,7);
                        ++it;
                }
        }
        std::cout << "v:";
        for(auto it = v.ibegin();it != v.iend();it++)
        {
                std::cout << it->num << " ";
        }
        std::cout << std::endl;

        std::cout << "v1:";
        for(auto it = v1.ibegin();it != v1.iend();++it)
        {
                std::cout << it->num << " ";
        }
        std::cout << std::endl;
        for(auto it = v1.ibegin();it != v1.iend();++it)
        {
                if(it->num == 4)
                {
                        it = v1.erase(it);
                        ++it;
                }
        }
        std::cout << "v1:";
        for(auto it = v1.ibegin();it != v1.iend();++it)
        {
                std::cout << it->num << " ";
        }
        std::cout << std::endl;

        std::cout << "v2:";
        for(auto it = v2.ibegin();it != v2.iend();it++)
        {
                std::cout << it->num << " ";
        }
        std::cout << std::endl;

        auto it_v3_end = v3.iend();
        std::cout << "*(it_v3_end--):" << (it_v3_end--)->num << std::endl;
        std::cout << "*(--it_v3_end):" << (--it_v3_end)->num << std::endl;

        return 0;
}

结果示例:

demo2:

        对象池

结构图:

 run.sh

#!/bin/bash
 
if [ -f ./Makefile ]
then
        make clean
fi
 
cmake .
 
make
 
echo "---------------------------------"
 
./pro

CMakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.28)                            #最低版本要求
 
SET(CMAKE_CXX_COMPILER "g++-11")                                #设置g++编译器
 
PROJECT(CLASS)                                                  #设置工程名
 
MESSAGE(STATUS "CPP test")                                      #打印消息
 
ADD_EXECUTABLE(pro test.cpp)                                    #生成可执行文件

clean.sh

rm -rf CMakeCache.txt CMakeFiles Makefile cmake_install.cmake *.o pro

test.cpp

#include <iostream>
#include <time.h>

template<typename T>
class Queue
{
        public:
                Queue()
                {
                        front = rear = new QueueItem(); 
                }
                ~Queue()
                {
                        QueueItem *tmp = front;
                        while(tmp != nullptr)
                        {
                                front = front->next;
                                delete tmp;
                                tmp = front;
                        }
                }

                void push(const T& val)
                {
                        QueueItem *tmp = new QueueItem(val);
                        rear->next = tmp;
                        rear = tmp;
                }

                void pop()
                {
                        if(empty())
                                return;
                        QueueItem* tmp = front->next;
                        front->next = tmp->next;

                        if (front->next == nullptr)
                        {
                                rear = front;
                        }
                        delete tmp;
                }

                bool empty()
                {
                        return front == rear;
                }

        private:
                struct QueueItem
                {
                        QueueItem(T data = T())
                                :data(data)
                                 ,next(nullptr){};

                        static void * operator new(size_t size)
                        {
                                if(itempool == nullptr )
                                {
                                        itempool = (QueueItem*)new char[sizeof(QueueItem) * POOL_SIZE];
                                        QueueItem *tmp = itempool;
                                        for(;tmp < itempool + POOL_SIZE - 1;tmp++)
                                        {
                                                tmp->next = tmp + 1;
                                        }              
                                        tmp->next = nullptr;
                                }

                                QueueItem *tmp = itempool;
                                itempool = itempool->next;
                                return tmp;
                        }

                        static void operator delete(void *p)
                        {
                                QueueItem* tmp = (QueueItem*)p; 
                                tmp->next = itempool;
                                itempool = tmp;
                        }

                        T data;
                        QueueItem *next;
                        static QueueItem* itempool;
                        static const unsigned int POOL_SIZE = 1000000;
                };

                static int num;
                QueueItem *front;
                QueueItem *rear;
};

template<typename T> 
typename Queue<T>::QueueItem* Queue<T>::QueueItem::itempool = nullptr;

class Test
{
        public:
                Test(){};
                Test(int n){};
                ~Test(){};
        private:
};


int main()
{
        Queue<Test> t;
        for(int i = 0;i < 1000000;i++)
        {
                t.push(Test(i));
                t.pop();
        }

        std::cout << "run time: " <<(double)clock() / CLOCKS_PER_SEC << "s" << std::endl;
        return 0;
}

结果示例:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938352.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

动态规划——最长公共子序列

文章目录 概要整体流程问题描述递推公式由来两个序列的最后一位相等两个序列的最后一位不等左图右图 表格填写dp 表格定义递推公式填表过程填表过程解析最终结果 小结 概要 动态规划相关知识 求解最长的公共子序列 整体流程 问题定义与区分&#xff1a;理解最长公共子串与最…

Node的学习以及学习通过Node书写接口并简单操作数据库

Node的学习 Node的基础上述是关于Node的一些基础&#xff0c;总结的还行&#xff1b; 利用Node书写接口并操作数据库 1. 初始化项目 创建新的项目文件夹&#xff0c;并初始化 package.json mkdir my-backend cd my-backend npm init -y2. 安装必要的依赖 安装Express.js&…

arXiv-2024 | NavAgent:基于多尺度城市街道视图融合的无人机视觉语言导航

作者&#xff1a;Youzhi Liu, Fanglong Yao*, Yuanchang Yue, Guangluan Xu, Xian Sun, Kun Fu 单位&#xff1a;中国科学院大学电子电气与通信工程学院&#xff0c;中国科学院空天信息创新研究院网络信息系统技术重点实验室 原文链接&#xff1a;NavAgent: Multi-scale Urba…

易语言鼠标轨迹算法(游戏防检测算法)

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

Three.js材质纹理扩散过渡

Three.js材质纹理扩散过渡 import * as THREE from "three"; import { ThreeHelper } from "/src/ThreeHelper"; import { LoadGLTF, MethodBaseSceneSet } from "/src/ThreeHelper/decorators"; import { MainScreen } from "/src/compone…

apache-tomcat-6.0.44.exe Win10

apache-tomcat-6.0.44.exe Win10

赫布定律 | 机器学习 / 反向传播 / 经验 / 习惯

注&#xff1a;本文为 “赫布定律” 相关文章合辑。 未整理。 赫布定律 Hebb‘s law 馥墨轩 2021 年 03 月 13 日 00:03 1 赫布集合的基本定义 唐纳德・赫布&#xff08;Donald Hebb&#xff09;在 1949 年出版了《行为的组织》&#xff08;The Organization of Behavior&a…

uni-app实现小程序、H5图片轮播预览、双指缩放、双击放大、单击还原、滑动切换功能

前言 这次的标题有点长&#xff0c;主要是想要表述的功能点有点多&#xff1b; 简单做一下需求描述 产品要求在商品详情页的头部轮播图部分&#xff0c;可以单击预览大图&#xff0c;同时在预览界面可以双指放大缩小图片并且可以移动查看图片&#xff0c;双击放大&#xff0…

杭州乘云联合信通院发布《云计算智能化可观测性能力成熟度模型》

原文地址&#xff1a;杭州乘云联合中国信通院等单位正式发布《云计算智能化可观测性能力成熟度模型》标准 2024年12月3日&#xff0c;由全球数字经济大会组委会主办、中国信通院承办的 2024全球数字经济大会 云AI计算创新发展大会&#xff08;2024 Cloud AI Compute Ignite&…

第6章图6.21-6.27-《分析模式》原图和UML图对比

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集

如何在谷歌浏览器中设置广告屏蔽

在数字时代&#xff0c;网络广告无处不在&#xff0c;虽然它们为网站提供了收入来源&#xff0c;但有时也会干扰我们的浏览体验。如果你正在寻找一种方法来减少这些干扰&#xff0c;那么在谷歌浏览器中设置广告屏蔽是一个不错的选择。本文将指导你完成这一过程&#xff0c;并简…

认识网络互联设备(二)

交换机 功能&#xff1a; &#xff08;1&#xff09;通过支持并行通信&#xff0c;提高交换机的信息吞吐量&#xff1b; &#xff08;2&#xff09;将传统的一个大局域网上的用户分若干工作组&#xff0c;每个端口连接一台设备或者连接一个工作组&#xff0c;有效的解决了拥塞情…

数据可视化-2. 条形图

目录 1. 条形图适用场景分析 1.1 比较不同类别的数据 1.2 展示数据分布 1.3 强调特定数据点 1.4 展示时间序列数据的对比 1.5 数据可视化教育 1.6 特定领域的应用 2. 条形图局限性 3. 条形图图代码实现 3.1 Python 源代码 3.2 条形图效果&#xff08;网页显示&#…

AMBA-CHI协议详解(十二)

AMBA-CHI协议详解&#xff08;一&#xff09;- Introduction AMBA-CHI协议详解&#xff08;二&#xff09;- Channel fields / Read transactions AMBA-CHI协议详解&#xff08;三&#xff09;- Write transactions AMBA-CHI协议详解&#xff08;四&#xff09;- Other transac…

【MATLAB第109期】基于MATLAB的带置信区间的RSA区域敏感性分析方法,无目标函数

【MATLAB第108期】基于MATLAB的带置信区间的RSA区域敏感性分析方法&#xff0c;无目标函数 参考第64期文章【MATLAB第64期】【保姆级教程】基于MATLAB的SOBOL全局敏感性分析模型运用&#xff08;含无目标函数&#xff0c;考虑代理模型&#xff09; 创新点&#xff1a; 1、采…

《外国服务区加油站模型:功能与美观的完美结合 caotu66.com》

这个外国服务区加油站模型在设计上独具特色&#xff0c;兼具实用性和美观性。 从整体布局来看&#xff0c;加油站位于服务区的显眼位置。加油站的顶棚采用了现代风格的设计&#xff0c;顶棚的颜色主要是黄色和蓝色&#xff0c;色彩鲜明且具有辨识度。顶棚下方有多个加油柱&…

mybatis-plus超详细讲解

mybatis-plus &#xff08;简化代码神器&#xff09; 地址&#xff1a;https://mp.baomidou.com/ 目录 mybatis-plus 简介 特性 支持数据库 参与贡献 快速指南 1、创建数据库 mybatis_plus 2、导入相关的依赖 3、创建对应的文件夹 4、编写配置文件 5、编写代码 …

数据结构(顺序表)JAVA方法的介绍

前言 在 Java 中&#xff0c;集合类&#xff08;Collections&#xff09;是构建高效程序的核心组件之一&#xff0c;而 List 接口作为集合框架中的重要一员&#xff0c;是一个有序、可重复的元素集合。与 Set 接口不同&#xff0c;List 保证了元素的顺序性&#xff0c;并允许存…

泊松编辑 possion editing图像合成笔记

开源地址&#xff1a; GitHub - kono-dada/Reproduction-of-possion-image-editing 掩码必须是矩形框

【Flink-scala】DataStream编程模型之状态编程

DataStream编程模型之状态编程 参考&#xff1a; 1.【Flink-Scala】DataStream编程模型之数据源、数据转换、数据输出 2.【Flink-scala】DataStream编程模型之 窗口的划分-时间概念-窗口计算程序 3.【Flink-scala】DataStream编程模型之窗口计算-触发器-驱逐器 4.【Flink-scal…