Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 库中的“新建”和“删除”操作符替代_C++_New Operator_Delete Operator - Fatal编程技术网

C++ 库中的“新建”和“删除”操作符替代

C++ 库中的“新建”和“删除”操作符替代,c++,new-operator,delete-operator,C++,New Operator,Delete Operator,如果两个库(dynamicali链接)拥有自己的全局覆盖版本的new和delete操作符,并且它们使用自己的内存管理,会发生什么情况 在库中提供内存管理设施通常是错误的,或者在某些情况下只为某些特定的类提供内存管理,只定义特定于类的new和delete操作符覆盖,这是好的吗 静态链接库的情况是否有一些不同?一般来说,这被标记为“这里是龙”。这取决于各种各样的事情。通常这两个库会发生冲突,new和delete最终会被其中一个库覆盖——这是您所能期望的最好结果 备选方案: 图书馆A启动了。覆盖新建

如果两个库(dynamicali链接)拥有自己的全局覆盖版本的newdelete操作符,并且它们使用自己的内存管理,会发生什么情况

在库中提供内存管理设施通常是错误的,或者在某些情况下只为某些特定的类提供内存管理,只定义特定于类的newdelete操作符覆盖,这是好的吗


静态链接库的情况是否有一些不同?

一般来说,这被标记为“这里是龙”。这取决于各种各样的事情。通常这两个库会发生冲突,new和delete最终会被其中一个库覆盖——这是您所能期望的最好结果

备选方案:

  • 图书馆A启动了。覆盖新建/删除,分配一些内存。库B启动并覆盖。在系统关闭时,库A的内存会随着库B的删除而释放。那不好

  • 库A中分配的内存使用库A的重写,库B也是如此。如果最终库B释放了库A中分配的内存,则会丢失。(这可能会更让人困惑,因为如果B删除的对象有一个虚拟析构函数,那么删除可能最终由a完成……所以它可以工作。)


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

例如,如果您查看std::vector,您会注意到它在存储的类型上以及在分配器上都是模板化的。通过编写一致的分配器,您可以精确地控制std::vector如何分配和取消分配内存。请注意这是多么美妙和松散耦合:即使不能更改任何原始std::vector源代码,也可以完全控制内存分配

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

  • 以std::allocator的方式编写符合分配器概念的分配器
  • 确保所有直接使用动态内存分配(例如,不通过其成员之一)的类都是分配器感知的
  • Typedef所有这些类,以便它们在默认情况下使用您的分配器
  • 为了澄清第3步,我的意思是在库的基本头文件中编写如下内容:

    template <class T>
    using my_lib::vector = std::vector<T, my_lib::MyAllocator<T>>;
    
    模板
    使用my_lib::vector=std::vector;
    
    现在,您可以在库中的任何位置使用“向量”,这将是一个普通向量,但使用您的分配方案

    步骤1可以是非常简单的(对于无状态分配器)也可以是非常棘手的(对于有状态分配器有很多问题)。至于步骤2,对于容器的动态内存来说非常简单,因为标准库中的所有容器都已经支持这一点。但是,如果您使用动态内存(例如多态性),您将需要做一些额外的工作(可能编写一个合适的包装器),以一种支持分配器的方式完成这项工作

    如果有人举了一些很好的例子,说明为什么您希望覆盖new/delete而不是使用分配器(例如,因为有些事情您不能使用分配器),我很想听听他们


    编辑:为了完整地说明这一点,请注意,如果同时使用库A和库B,则不会出现任何问题,因为没有覆盖全局运算符。

    您有特定的用例吗<代码>新建和
    删除
    可以被覆盖,但有什么用?或者,这是一个理论问题(对于高级用户和我想使用的)?动态链接库不存在于标准C++,所以你的问题是平台特定的。您对特定平台感兴趣吗?@SebastianRedl unix-related。so@Elyasin用例:内存池实现我认为“这里是龙”的意思足够清楚,可以表示“不要那样做”,但是+1表示建议了一个好的替代方案。@MartinBonner你说得对,我对问题/答案有点误读。让我改变一下措辞,我并不是想简短地推销你的好答案。