我应该对不透明对象使用整数 ID 还是指针?

2023-12-20

我正在一些图形 API(DirectX9 和 DirectX11)之上编写一个抽象层,我想听听您的意见。

传统上,我会为每个我想要抽象的概念创建一个基类。
因此,在典型的 OO 方式中,我将拥有一个 Shader 类和 2 个子类 DX9Shader 和 DX11Shader。

我会重复纹理等的过程...当我需要实例化它们时,我有一个抽象工厂,它将根据当前的图形 API 返回适当的子类。
遵循 RAII,返回的指针将封装在 std::shared_ptr 中。

到目前为止一切顺利,但就我而言,这种方法存在一些问题:

  1. 我需要提出一个公共接口来封装这两个 API(以及未来的其他 API)的功能。
  2. 派生类存储在单独的 DLL 中(一个用于 DX9,一个用于 DX11 等...),并且在客户端中对它们拥有一个 Shared_ptr 是一种诅咒:在退出时,图形 DLL 会被卸载,并且如果客户端仍然有一个 Shared_ptr图形对象之一boom,由于从卸载的 DLL 调用代码而崩溃。

这促使我重新设计我的做事方式: 我以为我可以将原始指针返回到资源,然后让图形 API 清理干净,但仍然存在客户端悬空指针和接口问题。 我什至考虑过像 COM 这样的手动引用计数,但我认为这将是一种倒退(如果我错了,请纠正我,来自shared_ptr 世界,手动引用计数似乎很原始)。

然后我看到了 Humus 的工作,其中他的所有图形类都由整数 ID 表示(很像 OpenGL 所做的)。 创建一个新对象仅返回其整数ID,并在内部存储指针;一切都是完全不透明的!

代表抽象的类(例如 DX9Shader 等)都隐藏在设备 API 后面,这是唯一的接口。
如果想要设置纹理,只需调用 device->SetTexture(ID) 即可,其余的都在幕后发生。

缺点是 API 的隐藏部分过于臃肿,需要大量样板代码才能使其工作,而且我不喜欢全能类。

有什么想法/想法吗?


您说主要问题是 DLL 被卸载,但仍然有指向其内部的指针。出色地...不要那样做。你有一个类实例,它的成员是实施的在该 DLL 中。它从根本上来说是一个error只要这些类实例存在,该 DLL 就会被卸载。

因此,您需要对如何使用此抽象负责。正如你需要负责一样any从 DLL 加载的代码:在卸载 DLL 之前,必须清除来自 DLL 的内容。如何做到这一点取决于您。您可以有一个内部引用计数,该计数对于 DLL 返回的每个对象都会递增,并且仅在所有引用的对象消失后才卸载 DLL。或者任何东西,真的。

毕竟,即使您使用这些不透明的数字或其他什么,如果您在卸载 DLL 时对该数字调用这些 API 函数之一,会发生什么情况?哎呀...所以它并不能真正为您带来任何保护。无论哪种方式你都必须负责。

您可能没有考虑到的数字方法的缺点是:

  • 降低了解物体实际含义的能力is。 API 调用可能会失败,因为您传递的数字并不是真正的对象。或者更糟糕的是,如果将着色器对象传递给采用纹理的函数会发生什么?也许我们正在讨论一个需要着色器和纹理的函数,而您不小心忘记了参数的顺序?如果这些是对象指针,C++ 的规则甚至不允许该代码编译。但是对于整数呢?都很好;你只会得到运行时错误。

  • 表现。每个 API 调用都必须在哈希表或其他内容中查找该数字,以获得要使用的实际指针。如果它是一个哈希表(即:一个数组),那么它可能相当小。但这仍然是一个间接的。由于您的抽象看起来级别非常低,因此在性能关键的情况下,此级别的任何性能损失都会真正受到损害。

  • 缺乏 RAII 和其他范围机制。当然,你可以写一个shared_ptr-esque 对象将创建和删除它们。但如果您使用实际的指针,则不必这样做。

这似乎不值得。

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

我应该对不透明对象使用整数 ID 还是指针? 的相关文章

随机推荐

  • DCG和左递归

    我正在尝试实现一个 dcg 它采用一组 a b c d 形式的字符串 我遇到的问题是 如果我有一个 s a c b 它返回 true 这是正确的答案 但是当我有 s a c f 形式的查询时 它不会返回答案 并且会耗尽本地堆栈 s gt s
  • ftp_get 不适用于大文件

    这是我的代码 con ftp connect ftpserver com ftp login con username password ftp pasv con true ftp set option con FTP TIMEOUT SE
  • create-react-app 不会生成 public 和 src 文件夹,因此无法启动

    我已经安装 CRA 一个多月了 并且一直在使用它 没有任何问题 但是今天我创建了一个新的 React 应用程序 它构建了文件夹和目录 但它不生成 src 和公共文件夹 它只是生成节点 module 文件夹 因此当我运行 npm start
  • Cordova/phonegap 活动生命周期

    我正在cordova应用程序中为android开发一个地图插件 让我们暂时忘记已经有不止一个了 并认为这是一个学术问题 的文档MapView states http developer android com reference com g
  • PhoneGap/Cordova iOS:捕获有持续时间限制的视频(即 30 秒)

    我想将视频捕捉时间限制为 30 秒 截至目前 PhoneGap 文档说明了 iOS 实现的以下内容 不支持持续时间参数 无法以编程方式限制录制长度 我确实找到了这篇文章 它似乎给出了纯粹客观的 C 实现的解决方案 iPhone 5秒视频拍摄
  • os_signpost 在模拟器上有效,但在设备上运行时无效

    我想使用仪器跟踪时间的函数之一中有以下代码行 当我从仪器在模拟器上运行该应用程序时 使用 os signpost 测量的时间确实显示出来 我可以准确地测量我需要的东西 Then I switch to device same code Ho
  • R - 分割数据框并保存到不同的文件

    我有一个数据框 其中包含多个地点的每月温度数据 gt df4 1 36 location variable cut month year freq 1 Adamantina temperature 10 Jan 1981 21 0 646
  • 如何消除 SSIS 作业中的“未使用的输出列”警告?

    我正在尝试消除 SSIS 进度日志中的一些虚假警告 我收到一堆关于使用原始 SQL 完成工作的任务中未使用列的警告 我有一个数据流 负责在加载新数据之前将数据归档到临时表中 数据流如下所示 OLEDB Source task read st
  • Xcode 是否隐式将 plist 转换为二进制格式?

    Xcode 在构建过程中是否会隐式地将项目中的 plist 转换为二进制文件 我不认为它隐式地这样做 但很难确定 有一个名为 Property List Output Encoding 又名 PLIST FILE OUTPUT FORMAT
  • 如何修复SSL证书验证失败

    我在本地使用 PHPMailer Apache 和 PHP 当我测试我的 SSL 配置和我的 cacerts 时 我得到 default cert file C Program Files Common Files SSL cert pem
  • 在VB.NET中使用Moq的VerifySet

    我有一个功能可以更新 ASP NET 会员资格提供程序中的用户
  • Python Kivy:如何在单击按钮时调用函数?

    我对使用 kivy 库还很陌生 我有一个 app py 文件和一个 app kv 文件 我的问题是我无法在按下按钮时调用函数 app py import kivy from kivy app import App from kivy uix
  • 如何在 wpf 中使用 WindowChrome 而不使用 Windows Aero 玻璃效果,黑色边框

    我正在尝试使用 WindowChrome 类自定义窗口边框 没有 Windows Aero 玻璃效果 正如预期的那样 我最终得到了一个黑人寄宿生 但我最终也没有标题按钮 从微软我了解到我可以通过将窗口样式设置为 null 来使用标准窗口来克
  • DQL 查询返回:预期 StateFieldPathExpression 或 SingleValuedAssociationField

    我有以下 DQL 查询 public function findByIdJoinedToCodeExample pageId query this gt getEntityManager gt createQuery SELECT c FR
  • 将 super 与 class_eval 一起使用

    我有一个应用程序 其中包含用于添加客户端自定义的核心类模块 我发现 class eval 是重写核心类中方法的好方法 但有时我想避免重写整个方法 而只是遵循原始方法 例如 如果我有一个名为account balance 最好在我的模块 即包
  • 在 ASP.NET 中将 HTML 内容写入 Word 文档时出现问题

    我正在尝试将 HTML 页面内容导出到 Word 我的Html显示页面是 你最喜欢的颜色是什么 NA 列出前三名的学校 一名国家级 两个开发人员 三个PS 以及一个用于点击事件的按钮 按钮单击事件将打开 MS Word 并将页面内容粘贴到
  • 简单的 UIView drawRect 没有被调用

    我不明白这里出了什么问题 我有一个非常简单的 UIViewController 和一个非常简单的 viewDidLoad 方法 void viewDidLoad NSLog making game view GameView v GameV
  • Python-获取目录中所有文件和子文件夹的相对路径

    我正在寻找一种获取特定文件夹内文件和 子 文件夹的相对路径的好方法 对于我目前使用的方法os walk 它正在工作 但对我来说似乎并不 Pythonic myFolder myfolder fileSet set yes I need a
  • 手动设置Session过期时间-CodeIgniter

    如何在 codeigniter 中动态设置会话过期时间 例如 如果用户登录并具有以下角色 admin 过期时间应该比没有权限的用户登录时要长admin role Thanks 您可以通过在配置文件中增加此变量来更新会话过期时间 config
  • 我应该对不透明对象使用整数 ID 还是指针?

    我正在一些图形 API DirectX9 和 DirectX11 之上编写一个抽象层 我想听听您的意见 传统上 我会为每个我想要抽象的概念创建一个基类 因此 在典型的 OO 方式中 我将拥有一个 Shader 类和 2 个子类 DX9Sha