本文主要探讨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 "---------------------------------"
 
./proCMakeLists.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 protest.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 "---------------------------------"
 
./proCMakeLists.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 protest.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;
}结果示例:




















