c++理解(三)

news2024/12/18 15:18:53

        本文主要探讨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;
}

结果示例:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「九」HarmonyOS 5 端云一体化实战项目——「M.U.」应用云侧开发云数据库

1 立意背景 M. 代表 “我”&#xff0c;U. 代表 “你”&#xff0c;这是一款用于记录情侣从相识、相知、相恋、见家长、订婚直至结婚等各个阶段美好记忆留存的应用程序。它旨在为情侣们提供一个专属的空间&#xff0c;让他们能够将一路走来的点点滴滴&#xff0c;如初次相遇时…

NVM:安装配置使用(详细教程)

文章目录 一、简介二、安装 nvm三、配置 nvm 镜像四、配置环境变量五、使用教程5.1 常用命令5.2 具体案例 六、结语 一、简介 在实际的开发和学习中可能会遇到不同项目的 node 版本不同&#xff0c;而出现的兼容性问题。 而 nvm 就可以很好的解决这个问题&#xff0c;它可以在…

Spark优化----Spark 数据倾斜

目录 数据倾斜的表现&#xff1a; 定位数据倾斜问题&#xff1a; 解决方案一&#xff1a;聚合原数据 避免 shuffle 过程 缩小 key 粒度&#xff08;增大数据倾斜可能性&#xff0c;降低每个 task 的数据量&#xff09; 增大 key 粒度&#xff08;减小数据倾斜可能性&#xff0c…

第十六届蓝桥杯模拟赛(第一期)-Python

本次模拟赛我认为涉及到的知识点&#xff1a; 分解质因数 Python的datetime库 位运算 简单dp 1、填空题 【问题描述】 如果一个数 p 是个质数&#xff0c;同时又是整数 a 的约数&#xff0c;则 p 称为 a 的一个质因数。 请问 2024 有多少个质因数。 【答案提交】 这是一道结…

MATLAB2021B APP seriallist 串口通信

文章目录 前言一、项目需要二、使用步骤1.查找串口填写到查找列表2.发送函数3. 接收函数4.检测串口按钮5.选择串口号 总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要&#xff1a; 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面…

OpenShift 4 - 多云管理(2) - 配置多集群观察功能

《OpenShift / RHEL / DevSecOps 汇总目录》 本文在 OpenShift 4.17 RHACM 2.12 环境中进行验证。 文章目录 多集群观察技术架构安装多集群观察功能监控多集群的运行状态监控多集群的应用运行在被管集群监控应用运行在管理集群监控被管集群的应用运行 参考 多集群观察技术架构…

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…

【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)

一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG&#xff08;Retrieval-augmented Generation&#xff0c;检索增强生成&#xff09;引擎。 主要作用&#xff1a; 让用户创建自有知识库&#xff0c;根据设定的参数对知识库中的文件进行切块处理&#xff0c;用户向大…

Android中坐标体系知识超详细讲解

说来说去都不如画图示意简单易懂啊&#xff01;&#xff01;&#xff01;真是的&#xff01; 来吧先上张图&#xff01; &#xff08;一&#xff09;首先明确一下android 中的坐标系统&#xff1a; 屏幕的左上角是坐标系统原点&#xff08;0,0&#xff09; 原点向右延伸是X轴正…

IO的进阶

目录 1. 字符流转向字节流的桥梁1.1 OutputStreamWriter1.2 InputStreamReader1.3 编码与解码1.4 常见编码方式1.5 编码与解码的注意事项 2.Properties2.1概述2.2 Properties 的常用方法2.3 Properties 的应用场景2.4 实例 3.序列化3.1 ObjectOutputStream 4.字符编码4.1 ASCII…

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备&#xff0c;转发器、网桥、路由器和网关有何区别&#xff1f; (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…

Edge Scdn用起来怎么样?

Edge Scdn&#xff1a;提升网站安全与性能的最佳选择 在当今互联网高速发展的时代&#xff0c;各种网络攻击层出不穷&#xff0c;特别是针对网站的DDoS攻击威胁&#xff0c;几乎每个行业都可能成为目标。为了确保网站的安全性与稳定性&#xff0c;越来越多的企业开始关注Edge …

UE4_控件蓝图_制作3D生命血条

一&#xff1a;效果图如下&#xff1a; 二、实现步骤&#xff1a; 1、新建敌人 右键蓝图类 选择角色&#xff0c; 重命名为BP_Enemytest。 双击打开&#xff0c;配置敌人网格体 修改位置及朝向 效果如下&#xff1a; 选择合适的动画蓝图类&#xff1a; 人物就有了动作&#x…

厦门凯酷全科技有限公司引领电商营销新风尚

在当今数字化经济快速发展的背景下&#xff0c;抖音作为领先的短视频和直播平台&#xff0c;已成为品牌推广和产品销售的重要渠道。厦门凯酷全科技有限公司&#xff08;以下简称“凯酷全”&#xff09;凭借其专业的团队和丰富的经验&#xff0c;专注于为客户提供高质量的抖音电…

高扬程潜水泵:大流量与高效率的完美结合|深圳鼎跃

洪水是由暴雨、风暴潮等等自然因素引起的江河湖海水量迅速增加或水位迅猛上涨的水流现象。一旦发生洪水事件&#xff0c;会侵袭河道沿岸的城市、农田等场景&#xff0c;在低洼地区容易形成积水&#xff0c;不仅影响人们的生活&#xff0c;还存在一定的安全风险。 高扬程潜水泵是…

神经网络基础-神经网络搭建和参数计算

文章目录 1.构建神经网络2. 神经网络的优缺点 1.构建神经网络 在 pytorch 中定义深度神经网络其实就是层堆叠的过程&#xff0c;继承自nn.Module&#xff0c;实现两个方法&#xff1a; __init__方法中定义网络中的层结构&#xff0c;主要是全连接层&#xff0c;并进行初始化。…

web网页前后端交互方式

参考该文&#xff0c; 一、前端通过表单<form>向后端发送数据 前端是通过html中的<form>表单&#xff0c;设置method属性定义发送表单数据的方式是get还是post。 如使用get方式&#xff0c;则提交的数据会在url中显示&#xff1b;如使用post方式&#xff0c;提交…

Mac配置 Node镜像源的时候报错解决办法

在Mac电脑中配置国内镜像源的时候报错,提示权限问题,无法写入配置文件。本文提供解决方法,青测有效。 一、原因分析 遇到的错误是由于 .npm 目录下的文件被 root 用户所拥有,导致当前用户无法写入相关配置文件。 二、解决办法 在终端输入以下命令,输入管理员密码即可。 su…

Linux实操篇-远程登录/Vim/开机重启

目录 传送门前言一、远程登录1、概念2、ifconfig3、实战3.1、SSH&#xff08;Secure Shell&#xff09;3.2、VNC&#xff08;Virtual Network Computing&#xff09;3.3、RDP&#xff08;Remote Desktop Protocol&#xff09;3.4、Telnet&#xff08;不推荐&#xff09;3.5、FT…

【C/C++进阶】CMake学习笔记

本篇文章包含的内容 一、CMake简介二、使用CMake构建工程2.1 一个最简单的CMake脚本2.2 使用变量和宏2.3 文件搜索 三、使用CMake制作和使用库文件3.1 静态库和动态库3.2 字符串操作3.3 CMake制作库文件3.4 CMake使用库文件3.4.1 使用link_libraries链接3.4.2 使用target_link_…