当前位置:  开发笔记 > 编程语言 > 正文

新建和删除操作符在库中覆盖

如何解决《新建和删除操作符在库中覆盖》经验,为你挑选了2个好方法。

如果两个库(动态链接)有自己的全局覆盖版本的newdelete运算符并且他们使用自己的内存管理会发生什么?

在库中运送内存管理工具通常是错误的,还是在某些情况下仅为某些特定类提供内存管理是好的,只定义特定于类的操作符和删除操作符覆盖?

在静态链接库的情况下是否存在一些差异?



1> Martin Bonne..:

一般来说,这被标记为"这里是龙".这取决于各种各样的事情.通常这两个图书馆都会打架,新的和删除最终会被其中一个图书馆覆盖 - 这是你所能想到的最好的.

备择方案:

图书馆A启动.覆盖new/delete,分配一些内存.图书馆B启动并覆盖.在系统关闭时,库A的内存被释放,库B被删除.这是不好的.

库A中分配的内存使用库A的覆盖,类似于库B.如果最终在库A中分配的内存被库B释放,则会丢失.(并且它可能更令人困惑,因为如果被B删除的对象具有虚拟析构函数,则删除最终可能由A完成...所以它可以工作.)



2> Nir Friedman..:

我认为马丁很好地回答了你的问题,概述了所发生的事情,也没有说它有点危险而且不是很明智(确实有龙).让我通过提供一个替代方案来扩展它:避免覆盖new/delete,而是使用allocator概念.

例如,如果你看一下std :: vector,你会注意到它存储的类型以及分配器都是模板化的.通过编写一致的分配器,您可以精确控制std :: vector如何分配和取消分配内存.注意这是多么好和松散耦合:即使你不能改变任何原始的std :: vector源代码,你也可以毫无困难地完全控制内存分配.

如果您希望库B以特定方式进行分配,我会做的是:

    以std :: allocator的方式编写符合分配器概念的分配器.

    确保所有直接使用动态内存分配的类(例如,不通过其中一个成员)都可以识别分配器.

    键入所有这些类,以便它们默认使用您的分配器.

为了澄清第3步,我的意思是在你的库的基本头文件中写这样的东西:

template 
using my_lib::vector = std::vector>;

现在你可以在你的库中的任何地方使用''vector'',这将是一个普通的向量,但使用你的分配方案.

第1步可以从非常简单(对于无状态分配器)到非常棘手(有很多有状态分配器).至于步骤2,就容器的动态内存而言,它非常简单,因为标准库中的所有容器都已支持此功能.但是如果你使用动态内存来实现多态性,那么你需要做一些额外的工作(可能写一个合适的包装器)来以分配器识别的方式完成这项工作.

如果某人有很好的理由说明为什么你想要覆盖new/delete而不是使用allocator(例如因为有些东西你不能用分配器),我会有兴趣听到它们.

编辑:只是为了得到这个完整的圆圈,请注意,如果你这样做,同时使用库A和B将没有任何问题,因为没有覆盖全局运算符.

推荐阅读
wurtjq
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有