`
qiezi
  • 浏览: 497248 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

抛开析构函数

    博客分类:
  • c++
阅读更多
内存管理通常指的是堆上分配的空间,栈上分配虽然高效好用,但一般是固定大小的、不能持久保存的。堆上分配就有了释放的问题,代码中有一些是使用new/malloc来分配空间的,还有一些是使用内存池,如何在释放时区分是必须的。

简单思考以后我感觉首先需要排除delete pObject这种调用,这显然是假定对象是用new分配出来的,或者是对象重载了new/delete操作符。也可以把对象根据分配方式不同放在不同的容器中管理,不过带来了查找上的开销。如果不分类放在容器中,也可以让对象自己知道是如何分配的,再给它一个销毁的函数:

struct Foo {
    int allocMethod;

    void Destroy() {
        switch(allocMethod) {
        case ALLOC_NEW: delete this; break;
        case ALLOC_MALLOC: // placement delete + free break;
        // ... memory pool or object pool
    }
};


这么写会很累,每个对象都要知道太多细节,可以考虑把这部分提出来:

struce DestroyCallback {
    virtual call(void* p) = 0;
};

struct Foo {
    DestroyCallback* destorycb;

    void Destory() {
        if (destroycb)
            destroycb->call(this);
    }
};

struct DeleteCallback : public DestroyCallback {
    virtual void call(void* p) {
        delete static_cast<Foo*>(p);
    }
};

struct PoolFreeCallback : public DestroyCallback {
    Pool<Foo>* pool;

    virtual void call(void* p) {
        pool->Release(static_cast<Foo*>(p));
    }
};


这种方式在分配对象的时候把destroy callback设置好,需要释放时调用Destroy就可以了,如果对象需要在一个流程中传递并且在最后阶段销毁,这种方式很容易解除前后端分配器的耦合。使用这种方式就需要用Destroy来代替其它销毁对象的方式,因为它并不一定真的表示销毁,对于对象池来说,它完成的是对象的归还。考虑到池对象重用时前需要初始化,我给对象加上一个初始化方法。由于Destroy并不能准确表明对象的生成状态,我改用Open/Close来代替,Open表明一个对象的重生,通常用来初始化一些变量的值,并不是取代构造函数,这特别适合一些需要池化的大对象,Close也不是析构,但它也可以真正完成析构调用。对于一些特殊的应用,还可以在Open里面完成构造函数调用,Close里面完成析构函数调用,如果对象的空间是使用malloc/free来管理的,这种方式就显得特别有用。这种方式还有一个额外的好处,很多C++开发者不喜欢使用异常,但构造函数没有返回值,只能使用异常来表示失败,多一个Open方法可以有一个不使用异常来检查错误的方法。
分享到:
评论
5 楼 qiezi 2008-01-24  
才看到上面这个评论。我就是从cppblog搬过来的,不太喜欢富文本。
4 楼 Uranus 2007-12-04  
建议楼主在CPPBLOG上导个博客,那边做CPP的人多
3 楼 qiezi 2007-08-16  
目前是把malloc/free和new/delete也包装成了,DestoryCallback一般只和分配器、对象池配套实现,不会有很多,DestoryCallback也实现成了模板接口,如果是单根类库就这个麻烦了。使用过程中感觉还是很灵活的。
2 楼 iunknown 2007-08-16  
不如再彻底一点,把直接使用 malloc/free, new/delete 的对象也归类为一种 pool 。这样所有的对象都是使用 pool 产生出来的。对于 Open/Close 的操作,就统一为 pool 的 create 和  release 操作。每个对象同样额外带着一个 pool 的指针。即把现在的 DestroyCallback 集成到 pool 中。这样就不再是有多种 DestroyCallback 的子类,而是有多种 pool 的子类。

这种思路在 apache 的 apr 项目中大规模地使用。
1 楼 iunknown 2007-08-16  
1.这种方式带来的问题是有很多小的 class 。如果使用 template ,可以减少一些。但起码对应不同的策略,就要有一种 DestroyCallback 的实现。
2.如果使用了 pool ,要保证 pool 和属于它的对象的生命周期要一致。

不过,考虑到这种方案所针对的问题,这种方案带来的问题比起能解决的问题,还是简化了。

相关推荐

    emd工具箱及所需要的函数

    emd+instfreq压缩包文件可能包含了完整的emd工具箱以及修正后的instfreq函数代码,用户下载后可以直接使用,避免了因缺失函数而导致的运行错误。为了充分利用这些资源,用户需要有一定的编程基础,比如熟悉MATLAB或...

    Scala函数式编程

    而在 Scala 的帮助下,这本书并不要求你抛开现有的思维方式另起炉灶,它所做的更像是为你现有的思维方式添砖加瓦,从而令你如虎添翼。  ——Spark committer from Databricks 连城  尽管函数式编程在近十多年用得...

    SQL Server 2005中的索引架构:抛开DBCC SHOWCONTIG,使用新的函数.pdf

    sysdm_dbindexphysical_stats()函数是一个表值函数,通过它可以获取索引的碎片信息,并且可以指定返回需要的行和列,从而过滤掉不必要的信息。此函数包含五个参数,每个参数都有默认值,如果不指定参数,它将返回...

    matlab emd工具箱

    只不过傅里叶变换以及小波变换都要求要有基函数,而EMD却完全抛开了基函数的束缚,仅仅依据数据自身的时间尺度特征来进行信号分解,具备自适应性。由于无需基函数,EMD几乎可以用于任何类型信号的分解,尤其是在非...

    200601-抛开偏见,正视保健品行业的投资机会_.rar

    这篇文档“200601-抛开偏见,正视保健品行业的投资机会_”可能为我们揭示了这一领域的诸多投资机遇与挑战。以下是根据标题和描述所推测的一些关键知识点: 1. **行业偏见与认知误区**:标题中的“抛开偏见”暗示了...

    初中语文文摘人生抛开纸枷锁

    【标题】"初中语文文摘人生抛开纸枷锁"主要探讨的是个人在生活中面临的各种社会期望和束缚,以及如何寻求自由和自我实现的过程。【描述】中提到的"纸枷锁"指的是那些看似重要但实际上可以轻易挣脱的束缚,比如传统...

    08.抛开偏见,正视保健品行业的投资机会_.rar

    抛开偏见,正视保健品行业的投资机会”这一主题提示我们关注的是保健品行业在投资领域的潜力和挑战。保健品行业涵盖了众多领域,如营养补充剂、健康食品、传统中药等,是现代人追求健康生活的重要组成部分。投资者在...

    操作系统的另类安装--抛开光盘

    ### 操作系统的另类安装——抛开光盘 在日常生活中,我们经常通过光盘来安装操作系统,然而在没有光驱、软驱甚至是U盘的情况下,如何实现操作系统的安装呢?本文将详细介绍一种无需借助传统媒介(如光盘)即可完成...

    C++的函数重载

    (抛开函数重载不谈,using就是一种解决命名冲突的方法,解决命名冲突还有很多其它的方法,这里就不论述了)2、当我们调用一个重载的函数时,又是如何去解析的?(即怎么知道调用的是哪个函数呢)这两个问题是任何...

    抛开软件让本本变身WiFi热点.docx

    ### 抛开软件让笔记本电脑变身WiFi热点 #### 第一步:以管理员身份运行命令提示符 要实现笔记本电脑变身为WiFi热点,首先需要确保你具备管理员权限。这一步至关重要,因为接下来的操作涉及到对系统级别的配置修改。...

    200601-抛开偏见,正视保健品行业的投资机会_.pdf

    200601-抛开偏见,正视保健品行业的投资机会_.pdf

    车企战略解读之六大集团篇 抛开销量谈转型 重点规划新能源汽车.pdf

    "车企战略解读之六大集团篇 抛开销量谈转型 重点规划新能源汽车" 本资源摘要信息来自六大汽车集团(一汽集团、东风汽车、上汽集团、长安汽车、北汽集团、广汽集团)的“十三五”战略规划,涵盖了新能源汽车、智能...

    package_emd.zip_HHT非平稳信号_信号分解_局部分解尺度_希尔伯特变换_希尔伯特黄

    只不过傅里叶变换以及小波变换都要求要有基函数,而EMD却完全抛开了基函数的束缚,仅仅依据数据自身的时间尺度特征来进行信号分解,具备自适应性。由于无需基函数,EMD几乎可以用于任何类型信号的分解,尤其是在非...

    抛开光驱装系统 U盘制作Win7系统教程

    两种方法教你使用U盘制作Win7系统教程

    12星座抛开元旦前烦恼的小妙招.doc

    【文档标题】与【描述】看似与IT行业不直接相关,但实际上,这是一份关于心理调适和星座运势的文档,旨在提供不同星座在迎接新年时如何处理烦恼的建议。以下将从星座角度出发,结合心理学知识,分析并提供一些通用的...

    操作系统的另类安装如何抛开光盘安装系统.pdf

    本文介绍了三种在没有光盘的情况下安装操作系统的替代方法,特别适合于光驱损坏、分区格式为NTFS或者硬盘损坏的情况。这些方法主要依赖于PE(预安装环境)工具和虚拟光驱技术。 首先,我们可以从硬盘中全新安装操作...

    食品饮料行业保健品板块投资策略:抛开偏见,正视保健品行业的投资机会-1016-信达证券-60页.pdf

    投资于保健品板块,投资者需要抛开偏见,正视该行业的投资机会。尽管保健品板块可能易受到短期政策及舆论波动的影响,但行业整体具有较高的防御性,主要源于其高频的消费模式、较高的利润贡献以及强防御性。保健品...

    初步解析Python中的yield函数的用法

    我们先抛开 generator,以一个常见的编程题目来展示 yield 的概念。 如何生成斐波那契數列 斐波那契(Fibonacci)數列是一个非常简单的递归数列,除第一个和第二个数外,任意一个数都可由前两个数相加得到。用计算机...

    新人教初中数学八年级下册反比例函数的图象和性质PPT课件.pptx

    如果抛开实际含义,这个函数的图象是一条经过原点的直线。而在问题2中,当面积为定值时,\( y \) 与 \( x \) 成反比,即 \( y = \frac{6}{x} \),其图象是双曲线的一部分。 双曲线是反比例函数的图象特征,它由两条...

Global site tag (gtag.js) - Google Analytics