使用自定义分配器调用对象构造函数/析构函数

2023-11-23

我一直在研究自定义分配器,并且经常看到它们使用某种函数来分配内存。为了测试目的并进一步教育我自己,我尝试制作一个“简单”的例子。然而,我知道如何做一件基本的事情。主要区别之一是malloc vs new是用 new 调用构造函数。如果我想编写自己的分配器来本质上替换怎么办new,在使用时如何调用构造函数malloc?

我知道在课堂上我可以超负荷new and delete对于班级来说,所以我想问题的很大一部分是,如何new在分配期间调用对象构造函数?同样,我感兴趣的是如何delete正在调用析构函数。

我创建了一个示例测试代码,我希望有SomeClass分配期间调用构造函数,但我不知道如何调用。

#include <malloc.h>

void* SomeAllocationFunction(size_t size) {
    return malloc(size);
}

class SomeClass
{
public:
    SomeClass() {
        int con = 1000;
    }

    ~SomeClass() {
        int des = 80;
    }
};

int main(void){
    SomeClass* t = (SomeClass*)SomeAllocationFunction(sizeof(SomeClass));
    return 0;
}

(作为注释,我知道我可以使用new。然而,为了学习的目的,我试图创建一个自定义分配器,它不仅仅调用new or placement new).


本质上,当您使用如下新表达式时:T *t = new T;,它大致相当于:

void *temp = operator new(sizeof(T));
T *t = new(temp) T;

因此,首先它使用分配函数分配一些原始内存,然后在该内存中构造一个对象。同样,当您使用如下删除表达式时:delete t;,它大致相当于:

t->~T();
operator delete(t);

所以,如果你超载new and delete对于特定类别:

class T { 
    int data; 
public:
    // I've made these static explicitly, but they'll be static even if you don't.
    static void *operator new(size_t size) { 
        return malloc(size);
    }
    static void operator delete(void *block) { 
        free(block);
    }
};

然后,当您使用新表达式时,它将调用该类'operator new分配内存,这将调用malloc, so T *t = new T();最终将通过分配内存malloc(同样,当你delete它,它将使用operator delete,这将调用free).

至少从通常使用的术语来看,分配器非常相似,只是它由容器而不是其他代码使用。它还将分配函数和删除函数封装到一个类中,因此当您将一个函数传递给容器时,只需传递一个对象,并且分配和删除函数不匹配的可能性很小。

暂时忽略有关事物名称的详细信息,即标准库中的 Allocator 类mostly做同样的事情,所以只需对函数中的函数进行一些重命名T完成上面的课程后,您就已经完成了标准分配器的一半编写工作。为了配合分配和删除,它有一个函数rebind一些内存(将内存块更改为另一种类型),就地创建一个对象(基本上只是围绕新放置的包装器)并销毁一个对象(同样,围绕析构函数调用的简单包装器)。当然,它使用operator new and operator delete代替malloc and free就像我上面用过的那样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用自定义分配器调用对象构造函数/析构函数 的相关文章

随机推荐

  • 将元胞数组的元胞数组转换为矩阵的矩阵

    我可以将矩阵元胞数组转换为矩阵 gt gt C 1 1 2 2 3 3 gt gt cell2mat C ans 1 1 2 2 3 3 还行吧 但是 我想将包含其他元胞数组的元胞数组转换为矩阵 gt gt C 1 1 2 2 3 3 gt
  • 使用 Powershell 查找文件中的多行模式

    如何使用 Powershell 在文件中查找多行模式 例如 XML 节点的内容 也就是说 如果我正在寻找 绿色 这个词deviceDescription节点 但 XML 节点文本可能跨越多行 这是行不通的 dir r i xml selec
  • 单击动态链接时深层链接不包含有效的必需参数

    我已将动态链接设置为文档 但单击链接时它显示 Deep Link does not contain valid required params URL params cpb 1 cpt cpit fpb CJsFEPcCGgVlbi1VUw
  • Azure AD B2C 向新用户发送邀请电子邮件

    通过使用新的 Azure AD B2C 服务预览版 我希望能够向用户发送邀请电子邮件以完成 SaaS 应用程序的注册 我们的每个客户都将管理自己的用户 我希望他们能够向新用户生成邀请电子邮件 以访问我们的 SaaS 应用程序 然后该用户将完
  • 字符串形式的月份名称

    我试图以字符串形式返回月份名称 例如 五月 九月 十一月 I tried int month c get Calendar MONTH 但是 这会返回整数 分别为 5 9 11 如何获取月份名称 用这个 Calendar cal Calen
  • Azure devops 报告生成器任务找不到coverage.cobertura.xml 文件

    正如标题所示 我正在尝试让代码覆盖率在 Azure Devops Pipeline 上运行 这是管道 trigger master pool vmImage windows latest variables solution sln bui
  • 我可以运行受密码保护的只读 git 服务器吗?

    我需要一个应用程序能够从 git 存储库获取但不能推送到它 所以 这是只读部分 这可以通过 git daemon 轻松完成 最重要的是 我需要访问受密码保护的所述存储库 包括读取它 因此 在进行任何获取之前 应用程序需要进行身份验证 可行吗
  • 为什么 null 是一个对象,null 和 undefined 有什么区别?

    Why is null被认为是object在 JavaScript 中 正在检查 if object null Do something 与 if object Do something 并且 有什么区别null and undefined
  • 使用需要不记名令牌的 API 在 Python 中进行 API 调用

    寻求有关将 JSON API 调用集成到 Python 程序中的帮助 我希望将以下 API 集成到 Python py 程序中 以允许调用它并打印响应 API 指南指出必须生成不记名令牌才能允许调用 API 我已成功完成此操作 但是 我不确
  • 有没有办法用 simple_form for Rails 提交 ajax/json 请求

    使用标准 Rails form for 我能够通过 select 和 collection select 帮助器传递 ajax 请求 如下所示 我似乎不知道如何做到这一点简单的形式 弄清楚了 你只需要添加这个 input html gt d
  • 使用 controlTransfer 方法设置奇偶校验

    有人知道如何在 Android 中设置与 controlTransfer 的奇偶校验吗 我在任何地方都找不到此方法参数的解释 只是参考文献中的一些通用信息 我发现的一个例子说 conn controlTransfer 0x40 0x04 0
  • 浮点文字与浮点变量的奇怪编译器行为

    我注意到 C 编译器的浮点舍入 截断有一个有趣的行为 也就是说 当浮点文字超出保证的可表示范围 7 位十进制数字 时 a 将浮点结果显式转换为浮点 语义上不必要的操作 和 b 将中间计算结果存储在局部变量中都会更改输出 一个例子 using
  • Heroku 和 GitHub:“无法检索项目,内部服务器错误”

    这篇文章涉及一个快速变化的事件 我只想连接到我的 GitHub 帐户 当我执行此操作时 我会在页面右上角收到以下红色小弹出窗口的错误消息 无法检索项目 内部服务器错误 截至 2022 年 5 月 25 日 19 52 世界标准时间 GitH
  • 比较两个列表的更新、删除和添加

    简单的问题 我有一个新列表和一个旧列表 在Java中是否有一个标准的方法 库允许我比较这两个列表并确定哪些项目已更新 删除或全新 例如 我最终应该得到三个列表 已删除的项目 旧的项目但不是新的项目 更新的项目 两者中的项目 新项目 新的项目
  • 如何使用 Dapper-dot-net 从单个 SP 映射多个记录

    我想在执行单个存储过程将返回 50 个多个单独的选择的情况下使用 Dapper 每个结果集都不会很宽 最多可能有 20 或 30 列 下面的代码来自 Dapper 测试 我想知道这个示例是否是一个很好的原型 谢谢你 斯蒂芬 public v
  • PHP Curl 下载前检查文件是否存在

    我正在编写一个 PHP 程序 从后端下载 pdf 并保存到本地驱动器 现在如何在下载前检查文件是否存在 目前我正在使用curl 参见下面的代码 来检查和下载 但它仍然下载大小为1KB的文件 url http wedsite test pdf
  • 当我们声明静态变量时,编译器实际上做了什么?

    我想知道幕后到底发生了什么 编译器如何处理静态变量 与自动变量不同 静态变量的值即使在块结束后仍然存在 但是编译器实际上如何处理这个问题 与堆栈上的局部变量不同 静态变量保存在特殊的数据段中 静态变量转到哪个段取决于它们是否初始化为 0 0
  • 跨平台和语言(反)序列化

    我正在寻找一种以最方便的方式序列化一堆 C 结构的方法 以便序列化可以跨 C 和 Java 至少 以及跨 32 位 64 位 大 小端平台移植 要序列化的结构仅包含数据 即它们是没有状态或行为的纯数据对象 我们的想法是 我们将结构序列化为一
  • 用于匹配化学式的严格正则表达式

    在使用 Perl 处理大型文本化学数据库的过程中 我遇到了使用正则表达式来匹配化学公式的问题 我见过these two之前的主题 但建议的答案对于我的要求来说太宽松了 具体来说 我的 诚然有限的 研究使我发现这个帖子它给出了当前接受的化学符
  • 使用自定义分配器调用对象构造函数/析构函数

    我一直在研究自定义分配器 并且经常看到它们使用某种函数来分配内存 为了测试目的并进一步教育我自己 我尝试制作一个 简单 的例子 然而 我知道如何做一件基本的事情 主要区别之一是malloc vs new是用 new 调用构造函数 如果我想编