明确表示对德尔福的所有权
Explicitly expressing ownership in Delphi
我主要是一名C++程序员,我已经习惯了使用std::unique_ptr
、std::shared_ptr
等类模板来表达我的对象的所有权。德尔福的标准库中是否有类似的东西?在编写代码时,是否有任何表达对象所有权的最佳实践?
编辑:自从C++11成为标准以来,有两个轻量级的帮助程序类,std::shared_ptr
和std::unique_ptr
。
如果我创建一个类型 std::shared_ptr<int>
的变量,它表示指向具有共享所有权的 int 的指针:在引擎盖下是引用计数,当引用计数达到零时,指针会自动释放。此类型表示一种"共享所有权",其中许多对象在完成资源时分担销毁资源的责任。
相比之下,std::unique_ptr
表示单一所有权。当unique_ptr超出范围时,将自动释放资源。std::unique_ptr 无法复制:一次只能有一个对象拥有此资源,并且只有一个对象负责清理该对象。
将这些轻量级类与指向 int 的裸指针进行对比,其中它可以表示共享所有权、唯一所有权,也可以只是对其他地方对象的引用!类型什么也没告诉你。
我的问题是:由于 Delphi 支持保存对对象的引用,是否有任何机制可以明确声明"我是这个对象的唯一所有者,当我完成它时,我将释放它",与"我只是为了与它交互而保留对这个对象的引用,但其他人会清理它"与"我与许多其他对象共享这个对象, 谁最后拥有它,谁就可以清理它。
我知道 Collections.Generics 有不同的集合,例如 TList
vs TObjectList
,其中 TObjectList 将释放存储在其中的成员,但 TList 不会。你可以说TObjectList"拥有"它的元素,而TList没有。这是我问题的本质,真的。在设计我自己的类时,有没有办法在语言中直接表达这些类型的所有权问题?或者是否有任何开发人员中常见的最佳实践/命名约定?
有任何语言结构可以提供帮助,也不知道任何"标准命名约定"。
但是,很久以前,我采用了以下命名约定,以便更轻松地检查类是否正确清理了它们:
- 根据标准的德尔菲约定,所有字段名称都以"F"开头。
- 类具有/承担终身管理责任的对象引用,以"FMy"开头。
- 接口引用类应该显式释放,通过在析构函数中将引用设置为 nil(为了性能,打破循环依赖关系等)以"FMi"开头
非常粗糙,但它有效,并且在浏览您有一段时间未见过的代码时有很大帮助,以防止那些"等等,该引用不应该被释放还是无效?"搜索。
std::unique_ptr 无法复制:一次只能有一个对象拥有此资源
在德尔菲语言中,没有任何类型或机制可以阻止共享"所有权"。始终可以复制任何参考。(阅读:德尔福中没有任何内容可以让你阻止分配,正如大卫所说的那样。
当unique_ptr超出范围时,将自动释放资源。
在德尔福,这只能通过(或通过)接口来实现。德尔福没有垃圾收集器。
并且只有一个对象负责清理对象。
清理的责任你必须自己执行。或者将该任务委托给(其他)框架。例如,默认的 Delphi VCL 类TComponent
实现了自动所有权(和销毁),可以选择与 RemoveComponent
和 InsertComponent
进行交换/控制。
在设计我自己的类时,有没有办法在语言中直接表达这些类型的所有权问题?或者是否有任何开发人员中常见的最佳实践/命名约定?
不完全是主题,但肯定相关:有多个"单例"设计模式实现强制执行对象的一次性创建。
关于命名约定:"所有者"(或您自己的示例中的"OwnsObjects")一词明确表示所有权,因为所有者将在必要时负责销毁。因此,使用窗体作为所有者(按钮的默认构造函数的单个参数)创建的按钮不需要手动销毁。
德尔福中的概念在很多情况下与C++不同。这两种语言都是第三代,但Delphi喜欢在比C++更高的抽象层次上工作。例如,Delphi 支持指针,但在引用概念时很少使用指针,这与 C++ 中的
指针概念并不完全相同。在 Delphi 中,对象变量实际上是引用(或者在较低级别的抽象中,它们是指针)。在C++中,当您声明一个对象变量时,构造函数会立即被调用,而在 Delphi 中则不是,您必须在给定的时刻调用它,这将分配内存并运行构造函数。因此,C++ 和 Delphi 中对象的内存管理受制于不同的生命周期。
说这些只是为了告诉你,德尔福的内存管理设计风格与C++不同。这就是为什么 Delphi 没有任何帮助程序类可以精确地执行您想要的操作。然而,德尔福提供了一个名为Interfaces
的概念,这在C++中是不存在的(至少,很久以前我曾经与C++一起工作时,它不存在)。接口类似于抽象类,因为它们没有代码。您必须为接口提供类实现器,该类将提供代码。但是,Interfaces
提供参考计数内存管理,我相信,它接近您正在寻找的内容。
所以,我对你的回答是:德尔福在内存管理方面为您提供的最接近的语言结构是接口。所以,我建议你至少研究一下,得出你自己的结论。
- C++结构到德尔福记录dll调用
- 如何在德尔福中C++制作与此类似的结构
- 德尔福在回调中出现 GUI 问题
- 我有点坚持德尔福的动态虚拟通道
- 加密和解密C++和德尔福中的一些字符串
- SDK指针的问题 - c++到德尔福的翻译
- 德尔福仿制药:E2037:'XXX'声明与以前的声明不同
- 德尔福动态DLL调用中的奇怪行为
- C++德尔福的int8_t[20]类型
- 如何在德尔福中C++参数数组指针算术
- 将德尔福记录与"polymorphic"转换为C / C ++
- 从C++ .dll到德尔福表单应用程序的PostMessage问题
- C++德尔福头文件翻译:带有指向 void 的指针的函数
- 明确表示对德尔福的所有权
- 德尔福中C++“const”返回类型相当于什么
- 将C++ FOR循环转换为德尔福
- 无法从德尔福文件安装嵌入C++生成器上的铬
- 从C++到德尔福的转换
- 德尔福复制记忆 vs C++ memcpy
- 如何将以下"class reference"机制从德尔福转换为C++11?