(delphi11最新学习资料) Object Pascal 学习笔记---第13章第3节 (仅销毁对象一次 )

13.3.2 仅销毁对象一次

​ 另一个问题是,如果调用对象的析构函数两次,将会导致错误。析构函数是释放对象内存的方法。我们可以为析构函数编写代码,通常是覆盖默认的 Destroy 析构函数,以便让对象在被销毁之前执行一些代码。

DestroyTObject类的虚析构函数。大多数需要在对象销毁时执行自定义清理代码的类都会覆盖此虚方法。您绝对不应该定义新的析构函数,因为通常对象是通过调用Free方法来销毁的,而Free方法会为您调用Destroy虚析构函数(可能是重载版本)。

​ 正如我刚提到的,Free只是TObject类的一个方法,被所有其他类继承。Free方法基本上在调用Destroy虚析构函数之前检查当前对象(Self)是否为nil

注解:您可能会想知道为什么如果对象引用为nil,您仍然可以安全地调用Free,但不能调用Destroy。原因是Free是一个位于给定内存位置的已知方法,而Destroy虚函数是在运行时查看对象的类型来确定的,如果对象不存在,这个操作就非常危险

​ 以下是Free的伪代码:

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;

​ 接下来,我们可以将注意力转向Assigned函数。当我们将指针传递给此函数时,它只是测试指针是否为nil。因此,以下两个语句在大多数情况下是等效的:

if Assigned(MyObj) then
  ...
if MyObj <> nil then
  ...

​ 请注意,这些语句仅测试指针是否不为nil;它们不检查它是否是有效的指针。如果您编写以下代码:

MyObj.Free;  //不会把MyObj设置为nil
if MyObj <> nil then
  MyObj.DoSomething;

测试将评估为True,并且在调用对象方法的行中会出现错误。需要注意的是,调用Free不会将对象的引用设置为nil

​ 自动将对象设置为nil是不可能的。您可能有多个引用指向同一个对象,而Object Pascal 不会跟踪它们。同时,在方法中(例如Free方法),我们可以操作对象,但我们对对象引用一无所知——即我们用于调用该方法的变量的内存地址。

​ 换句话说,在Free方法或类的其他任何方法中,我们知道对象(Self)的内存地址,但我们不知道引用对象的变量的内存位置,比如MyObj。因此,Free方法无法影响MyObj变量。

​ 然而,当我们将对象作为按引用传递参数的方式调用一个外部函数时,该函数随后可以选择修改原始对象引用。这正是FreeAndNil过程所做的事情,FreeAndNil过程可以替代使用Free然后将引用变量设置为nil。以下是FreeAndNil的代码:

procedure FreeAndNil(const [ref] Obj: TObject); inline;
var
  Temp: TObject;
begin
  Temp := Obj;
  TObject(Pointer(@Obj)^) := nil;
  Temp.Free;
end;

​ 在过去,参数只是一个指针,缺点是您可以将原始指针、接口引用和其他不兼容的数据结构传递给FreeAndNil过程。这通常会导致内存损坏和难以发现的错误。从Delphi 10.4开始,代码已被修改如上所示,使用TObject类型的const引用参数,将参数限制为对象。

注解:许多Delphi专家会争论,FreeAndNil永远不应该使用,因为引用对象的变量的可见性应该与其生命周期相匹配。如果对象拥有另一个对象并在析构函数中释放它,就不需要将引用设置为nil,因为它是不再使用的对象的一部分。同样,具有在try-finally块中释放的局部变量也不需要将其设置为nil,因为它即将退出作用域。

​ 顺便提了一下,除了Free方法之外,TObject还有一个DisposeOf方法,它是多年以前Object Pascal语言支持ARC的产物。目前,DisposeOf方法只是调用Free

​ 总结一下关于这些内存清理操作的使用,这里是一些建议:

  • 始终调用Free来销毁对象,而不是调用Destroy析构函数。
  • 在调用Free之后使用FreeAndNil,或将对象引用设置为nil,除非引用紧接着超出作用域。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/647842.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

5.23 Linux中超时检测方式+模拟面试

1.IO多路复用的原理&#xff1f; IO多路复用使得一个或少量线程资源处理多个连接的IO事件的技术。对于要处理的多个阻塞的IO操作&#xff0c;建立集合并存储它们的文件描述符&#xff0c;利用单个阻塞函数去监控集合中文件描述符事件到达的情况&#xff0c;&#xff08;如果到…

k8s部署presto

&#xff08;作者&#xff1a;陈玓玏&#xff09; 一、前提条件 已部署k8s&#xff1b;已部署hadoop和hive&#xff0c;可参考以下链接&#xff1a; https://blog.csdn.net/weixin_39750084/article/details/136750613?spm1001.2014.3001.5502 https://blog.csdn.net/wei…

【Linux-时间管理和内核定时器】

Linux-时间管理和内核定时器 ■ 设置系统节拍率■ 高节拍率和低节拍率的优缺点&#xff1a;■ jiffies 系统节拍数■ get_jiffies_64 这个函数可以获取 jiffies_64 的值■ 处理绕回■ 使用 jiffies 判断超时 ■ jiffies 和 ms、 us、 ns 之间的转换函数在这里插入代码片■ 内核…

Python语言基础学习(下)

目录 一、顺序语句 二、条件语句 (1) if (2) if - else (3) if - elif - else 缩进和代码块 空语句 pass 三、循环语句 while 循环 for 循环 continue break 四、函数 创建函数 调用函数 函数返回 函数变量 函数递归 关键字参数 五、列表和元组 创建列表 …

CNCAP2024主动安全解析

一、新增场景 车辆自动紧急制动系统&#xff08;AEB C2C&#xff09;在 2021 版基础上新增了叉路口场景、高速公路追尾场景和 AEB 误作用场景&#xff1b;VRU 自动紧急制动&#xff08;AEB VRU&#xff09;试验在 2021 版基础上新增了交叉路口场景&#xff0c;同时对已有场景进…

你真的了解HTTPS协议吗

前言 在 HTTP 协议中有可能存在信息窃听或身份伪装等安全问题。使用 HTTPS 通信机制可以有效地防止这些问题。本文即将带大家来了解这些。 任何事物都有两面性&#xff0c;为了满足HTTP协议的快&#xff0c;但导致了它有如下的不足&#xff1a; 通信采用明文&#xff08;不加…

IDEA 2024.1安装与破解

一、下载 官网地址&#xff1a;https://www.jetbrains.com/idea/download/other.html 二、安装 傻瓜式安装即可 三、破解 3.1 破解程序 网站&#xff1a;https://3.jetbra.in/ 3.2 获取激活码 点击*号部分即可复制成功

深入解析RPC技术:原理、实现与应用

RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09;是一种计算机通信协议&#xff0c;允许一个程序&#xff08;客户端&#xff09;在本地调用另一个程序&#xff08;服务器&#xff09;中的函数或方法&#xff0c;并获取返回结果&#xff0c;就像调用…

Dubbo生态之sentinel限流

1. 限流算法 我们知道&#xff0c;在分布式架构中&#xff0c;当服务请求量过大时&#xff0c;容易对服务器造成不可预知的压力&#xff0c;因此&#xff0c;我们在客户端请求的时候&#xff0c;进行限流&#xff0c;起到一个保护的作用 常见的限流算法有: 计数器限流&#x…

猫头虎 解析:为什么AIGC在国内适合做TOB,在国外适合做TOC?

猫头虎 解析&#xff1a;为什么AIGC在国内适合做TOB&#xff0c;在国外适合做TOC&#xff1f; 博主 猫头虎 的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面…

Golang | Leetcode Golang题解之第114题二叉树展开为链表

题目&#xff1a; 题解&#xff1a; func flatten(root *TreeNode) {curr : rootfor curr ! nil {if curr.Left ! nil {next : curr.Leftpredecessor : nextfor predecessor.Right ! nil {predecessor predecessor.Right}predecessor.Right curr.Rightcurr.Left, curr.Righ…

python数据分析——apply 1

参考资料&#xff1a;活用pandas库 apply是指把函数同时作用于DataFrame的每一行或每一列。类似于编写一些跨每行或每列的for循环&#xff0c;并同时调用apply函数。 1、函数 函数是对python代码进行分组和复用的一种方法。如果某段代码会被多次使用&#xff0c;并且使用时是需…

【C++】——入门基础知识超详解

目录 ​编辑 1.C关键字 2. 命名空间 2.1 命名空间定义 2.2 命名空间使用 命名空间的使用有三种方式&#xff1a; 注意事项 3. C输入&输出 示例 1&#xff1a;基本输入输出 示例 2&#xff1a;读取多个值 示例 3&#xff1a;处理字符串输入 示例 4&#xff1a;读…

部署PIM-SM

拓扑图 配置 使能组播路由 配置OSPF 组播路由器接口配置pim-sm 连接组成员的接口使能igmp pim路由器上配置静态RP sysname AR1 # multicast routing-enable # interface GigabitEthernet0/0/0ip address 10.1.12.1 255.255.255.0 pim sm # interface GigabitEthernet0/0/…

SpringBoot + MybatisPlus

SpringBoot MybatisPlus 整合记录 1. 硬件软件基本信息2. 相关链接3. 通过idea快速生成一个Springboot项目4. 启动报错问题解决问题一&#xff1a;Springboot启动的时候报错提示 “没有符合条件的Bean关于Mapper类型”问题二&#xff1a;启动的时候提示需要一个Bean&#xff0…

文件操作知识点

前言: 我们应该知道一般程序运行时产生的数据是存放在内存中的。但是如果程序关闭后这些内存就会被系统回收&#xff0c;如果内存内的有用的数据没有被保存下来&#xff0c;这些数据就丢失了。所以这个时候我们就可以使用磁盘来储存我们的数据。 目录 程序文件的分类 文件名…

第八篇【传奇开心果系列】Python微项目技术点案例示例:以微项目开发为案例,深度解读Dearpygui 编写图形化界面桌面程序的优势

传奇开心果博文系列 系列博文目录Python微项目技术点案例示例系列 博文目录前言一、开发图形化界面桌面程序的优势介绍二、跨平台特性示例代码和解析三、高性能特性示例代码和解析四、简单易用特性示例代码和解析五、扩展性强示例代码和解析六、现代化设计示例代码和解析七、知…

Android 快速调试网络 复制curl 到postMan

搜索这个插件 官网地址&#xff1a;https://github.com/itkacher/OkHttpProfiler 集成教程也在里面集成完毕后右下角有一个入口点进去可以复制curl| 插件名称&#xff1a;Okhttp Profiler 真的很好用&#xff01;

软测刷题-错题1

提高测试效率的方法&#xff1a; 1、不要做无效的测试 2.不要做重复的测试 3.不同测试版本的测试侧重点 4.优化测试顺序 LoadRunner是对服务器进行施压。 在数据库中存在的用户数是指注册用户数。 input标签可以直接使用send_keys实现上传&#xff0c;而非input标签是无法直…

指纹识别系统架构

目录 1. 系统架构 1.1 指纹采集模块 1.2 指纹处理模块 1.3 指纹登记模块 1.4 指纹识别模块 1.5 指纹识别决策模块 1.6 管理模块 1.6.1 存储管理 1.6.2 传输管理 1.6.3 安全管理 1.7 应用开放功能 1.7.1 指纹登记功能 1.7.2 指纹验证功能 1.7.3 指纹辨识功能 2. …