当前位置: 首页 > news >正文

C++的模板(十四):更多的自动内存管理

在前文《C++的模板(八):子系统》class DMM,给出了一个自动动态内存管理的例子。https://blog.csdn.net/aaasssdddd96/article/details/139921880

它使用了一个list容器,把两个类型兼容的指针存放在一起。在new的时候,随即就把得到的指针放进了list容器里。在管理器析构的时候,自动释放容器中的指针。这样避免了手动释放内存的问题。指针new出来就可以用了,不用自己释放,也不用担心内存泄漏。

现在做一点改造。采用更多的list容器来管理不同的new类型。让几乎每一种类型可以同样自动管理。根据前文的例子,问题的后一半已经有了答案,现在只要把list容器组装起来。

考虑到每个list容器,如list<int>,list<double>,原则上虽然都是list,具体到语法上却都是不同的类型。要把它们调整到一致。前文《C++的继承(十二):抽象类》给出了一种方法。https://blog.csdn.net/aaasssdddd96/article/details/146153593

如果还记得“吃饺子要沾点醋”这句话,现在就来用一下。就是让它们都继承一个空的抽象类。一个空的抽象类好比是“要沾的醋”。

class E{
public:
virtual ~E() {printf("~E\n");}
};
template <class C>
class M: public E
{
public:
        list<C*> l;
        C *newobj(C x) {
                C *p = new C(x);
                l.push_back(p);
                return p;
        }
        ~M() {printf("type:  M<%s>:\n", typeid(C).name());
                typename list<C*>::iterator it;
                for(it=l.begin(); it!=l.end(); ++it) {
                        if(typeid(C)==typeid(int)) {
                                printf("%d ", *(int*)*it);
                        }else if(typeid(C)==typeid(double)) {
                                printf("%lf ", *(double*)*it);
                        } else printf(". ");
                        delete *it;
                }
                printf("/.\n");
        }
};

各种list容器已经包装到了class M中,并且继承了共同的空类E。

现在把这些包装过的list容器组装进map模板。用内存分配的目标类型的typeid来进行索引。注意虽然是用typeid来进行索引这个概念。在具体实现上,由于编译器typeid返回的type_info类型做成了固定的const 类型,并且屏蔽了构造函数,复制,赋值这些操作,不能直接用它来构造map容器。需要用个代理来做这些事情。

class typeinfop {
        const type_info *tp;
public:
        typeinfop(const type_info *p){tp=p;}
        bool less(const type_info *t)const  {return tp->before( *t);}
        bool operator<(const typeinfop p) const {return less(p.tp);}
};

这个typeinfop将作为map模板的key来使用。注意作为map模板的key必须定义operator<()比较运算。

接下来就定义一个封装了map模板的简单类class SE。因为各种list容器已经统一继承了空类E。map模板的类型就是 map<typeinfop, E*>。类中含有一个newobj()模板成员函数和一个析构函数。析构函数会自动删除用E类包装的list容器。而这些list容器在析构时,又会自动删除内存分配new出去的对象指针。

class SE {
        map<typeinfop, E*> m;
public:
        template<class C>
        C *newobj(C x) {
                E* p;
                M<C>  *mp;
                p = m[typeinfop(&typeid(C))];
                if(!p) {
                        p = new M<C>;
                        m[typeinfop(&typeid(C))]=p;
                }
                mp = static_cast<M<C>*> (p);
                return mp->newobj(x);
        }
        ~SE() {
                map<typeinfop, E*>::iterator it;
                for(it=m.begin(); it!=m.end(); ++it) {
                        delete it->second;
                }
        }
}sm;

这就大功告成了。现在写个main()函数测试下看效果,new出来就不用管了:

#include <stdio.h>
#include <stdlib.h>
#include <list>
#include <map>
#include <typeinfo>
using namespace std;
int main()
{
        int *p;
        double *dp;
        dp= sm.newobj(3.1);
        p= sm.newobj(3);
        dp= sm.newobj(3.14);
        p= sm.newobj(4);
        dp= sm.newobj(3.141);
        p= sm.newobj(5);
        dp= sm.newobj(3.1415);
        int **pp = sm.newobj(p);
        double **dpp = sm.newobj(dp);
        return 0;
}

运行结果:

type:  M<Pd>:
. /.
~E
type:  M<Pi>:
. /.
~E
type:  M<d>:
3.100000 3.140000 3.141000 3.141500 /.
~E
type:  M<i>:
3 4 5 /.
~E

sm内存管理器自动生成了4个list容器。分别是list<double*>,list<int*>,list<double>和list<int>。打印的信息是析构函数里输出的,分配的每一个数据都得到了删除处理。

http://www.dtcms.com/a/99656.html

相关文章:

  • AI的未来在手机里!
  • Spring Data审计利器:@LastModifiedDate详解(依赖关系补充篇)!!!
  • springBoot与ElementUI配合上传文件
  • Vue2——常用指令总结、指令修饰符、v-model原理、computed计算属性、watch监听器、ref和$refs
  • Elasticsearch(ES)的经典面试题及其答案
  • 深度对比:DeepSeek vs OpenAI 核心技术指标
  • Matlab安装tdms插件
  • Numpy用法(三)
  • QT操作Excel
  • 【 <二> 丹方改良:Spring 时代的 JavaWeb】之 Spring Boot 中的缓存技术:使用 Redis 提升性能
  • NodeJs之http模块
  • 学成在线--day02
  • 深度学习篇---模型训练评估参数
  • Tabby二:使用笔记 - 保姆级教程
  • C#的CSV 在8859-1下中乱码和技巧
  • 猜猜我用的是哪个大模型?我的世界游戏界面简单的模拟效果
  • 网络华为HCIA+HCIP 策略路由,双点双向
  • OSPF练习
  • Let’s Encrypt 宣布推出短期证书与 IP 地址支持,推动 Web 安全迈向新高度
  • 无线通信技术(二):ITU、3GPP及传统波段对无线频谱的划分
  • AutoDev 2.0 正式发布:智能体 x 开源生态,AI 自动开发新标杆
  • 计算机组成原理笔记(六)——2.2机器数的定点表示和浮点表示
  • React Router精通:轻松创建动态单页应用
  • 动态IP:网络世界的“变色龙”如何改变你的在线体验?
  • 革新汽车安全通信技术,美格智能全系车载通信模组支持NG-eCall
  • Baklib知识中台驱动智能架构升级
  • HTML布局
  • HTML文档流
  • Turtle事件处理(键盘与鼠标交互)
  • 基于单片机的智能家居设计(论文+源码)