- 博客(159)
- 资源 (8)
- 收藏
- 关注
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第3节(泛型约束)
方法的类,当数据对象是特定类型时,该版本将被调用,而不管提供的实际类型是什么。将在数据对象是特定类型时被调用,而不管提供给泛类型的实际类型是什么。 正如我们所看到的,您在泛型类的方法中可以做的事情非常少。您还可以进一步限制类为给定层次结构的一部分,或实现特定接口,从而可以在泛型类型的实例上调用类或接口方法。值传递,也可以定义特定的泛型类型实例,在这两种情况下,调用One方法最终会执行特定版本的。 但是,不同的记录之间共同点很少(没有共同的祖先),因此这种声明有些受限。函数不同,后者返回引用类型的大小。
2024-06-13 06:00:00
374
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
实际上,编译器会生成一个这样的构造函数,并为每个泛型类实例调用这个构造函数,即为使用泛型模板定义每个实际类型。这非常有趣,因为如果没有构造函数,在您的程序中要创建的每个泛型类的实例,要执行初始化代码将非常复杂。每个泛型类的实例也会获得这种类类型数据的实例。如果您需要为类类型数据分配初始值,则无法使用Unit初始化代码,因为在定义泛型类的单元中,您不知道将需要哪些实际类。 但是,如果您在不同的单元中基于相同的数据类型创建泛型实例,则链接器可能无法按预期工作,并且您将拥有多个相同类型的泛型类构造函数。
2024-06-12 06:00:00
381
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类型函数 )
如果有一个 case 或 if 语句是基于这些函数之一的返回值,编译器立即就能算出,仅对于给定类型,其中一个分支将被执行,从而删除无用的代码。当针对不同类型编译相同的泛型方法时,可能会使用不同的分支,但编译器同样可以预先计算并优化方法的大小。返回类型的字节数(对于引用类型,如字符串或对象,它将是引用的大小,即32位编译器的4个字节,64位编译器的8个字节)单元的函数),而不是直接访问数据结构,因为它可以执行保持类型名称的字符串值编码的正确转换。返回指向当前版本的泛型类型的运行时信息的指针;
2024-06-11 06:00:00
482
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类型实例化)
同样,在不同单元中使用相同的泛型类型实例会强制编译器一遍又一遍地生成相同的代码,可能会导致显著的代码膨胀。因此,如果您有一个泛型类有许多不依赖于泛型类型的方法,则建议定义一个具有这些公共方法的非泛型基类,并具有泛型方法的继承泛型类:这样基类方法只编译一次并包含在可执行文件中。 除了一些优化之外,每次实例化泛型类型时,无论是在方法中还是在类中,编译器都会生成一个新的类型。 请注意,这是一个相当高级的一节内容,重点关注泛型的一些内部细节及其潜在的优化。如果这是您第一次学习泛型,那么建议您多读一遍。
2024-06-10 06:00:00
475
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第3节(接口引用 vs 泛型接口约束)
第一个不同点是,在上面的类中,只要它们的类都实现了给定的接口,就可以向setter方法传递两个不同类型的对象,而在泛型版本中,只能传递给定类型的对象或该类型的派生对象(传递给泛型类的任何给定实例)。此外,泛型版本可以具有多个约束,如构造函数约束,并允许您使用各种泛型函数(例如查询泛型类型的实际类型),而使用接口时则无法引用基类。 换句话说,使用带有接口约束的泛型类可以有接口的好处,而不会带来麻烦。不过,值得注意的是,在大多数情况下,这两种方法是等价的,而在另一些情况下,基于接口的解决方案则更为灵活。
2024-06-09 06:00:00
324
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第3节(特定类约束)
如果你考虑一下利用继承和类型兼容规则可以实现的功能,也许你可以使用传统的面向对象技术来解决同样的问题,而不必使用泛型类。我并不是说特定的类约束从来都没有用,但它肯定没有更高级别的类约束或(我觉得非常有趣的)基于接口的约束强大。 一般来说,更灵活的做法是只接受实现特定接口的类作为类型参数,而不是将一个泛型类约束为一个给定的类。这使您拥有一个非常特定的泛型类型(是的,听起来很奇怪,但这确实是它的实际情况),并且编译器将允许您在处理泛型类型时使用。 该类函数(此处未显示)在父控件中创建了一个随机位置的按钮。
2024-06-08 06:00:00
313
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(标准类的泛型方法)
使用泛型类型定义类可能是最常见的情况,但泛型类型也可以用于非泛型类。换句话说,一个普通的类也可以有一个泛型方法。在这种情况下,不仅要在创建类的实例时为泛型占位符指定类型,还要在调用方法时指定类型。:当我第一次编写这段代码时,可能是因为我想起了我的C++时代,我将参数写成了(t:T)。 所有上述调用都是正确的,因为这些调用中的参数类型可以是隐式的。如果使用类型和参数调用该方法,则参数的类型必须与泛型类型声明匹配。 如果在尖括号之间不指示类型调用该方法,则实际类型将从参数的类型中。
2024-06-07 20:06:18
380
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类型兼容性规则)
然而,编译器只允许您对那些类型兼容的数组进行赋值,要么是因为它们的类型具有相同的显式名称(如TArrayOf10),要么是因为它们具有与在单个语句中声明的数组相同的隐式(编译器生成的)类型名称。规则的另一个例外,也是一个重要的例外,是泛型类型的类型兼容性,这也可能被编译器在内部使用,以确定何时从泛型类型生成新类型及其所有方法。 新规则规定,当泛型类型具有相同的泛型类定义和实例类型时,它们是兼容的,而不再考虑与此定义相关联的类型名称。换句话说,泛型类型实例的完整名称是泛型类型和实例类型的组合。
2024-06-05 06:00:00
331
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(Object Pascal中的泛型)
我们将看到这种方法可能存在的缺点,但好的一面是泛型类与普通类一样高效,甚至更高效,因为减少了运行时检查的需要。 泛型类型可以用作字段的类型(如我在前面的例子中所做的那样),也可以用作属性的类型、函数的参数或返回值的类型等。请注意,对于本地字段(或数组),不强制使用类型,因为有些情况下泛型类型仅用作结果、参数或者在类的声明中没有使用,而只是在类的某些方法的定义中使用。中定义和使用泛型类。在从语言角度讨论泛型之后,我们将列举更多的例子,包括使用和定义泛型容器类,这是该语言中这种技术的主要用途之一。
2024-06-04 06:00:00
353
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第1节(泛型键值对)
一旦在泛型声明中定义了具体类型,编译器将强制执行对具体类型的检查,这符合Object Pascal等强类型语言的预期。当为对象指定泛型参数时,不能将一个不同且不兼容类型的相似泛型类型分配给它。 正如我们将在 "通用类型兼容性规则 "一节中看到的,在这种特殊情况下,类型兼容性规则是按结构而不是按类型名制定的。当你声明一个具体类型的对象时,你不能为 Value 字段指定不同的类型。 当你声明一个泛型类型的实例时,该类型会得到一个具体的版本,编译器会在所有后续操作中使用该版本。
2024-06-03 06:00:00
366
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型
虽然复制并粘贴原来的类创建一个新类是一种解决方案,但你最终会得到两份基本相同的代码副本,这有悖于良好的编程原则,而且还需要进行噩梦般的维护,因为你必须为每个副本更新新功能,或修复两份、三份或二十份几乎完全相同的副本中的相同错误。因此,你的应用程序中最终仍会编译两个、三个或二十个类,但所有这些类都有一个单一的源代码定义,它进行原生类型到类类型的类型检查,而且没有额外的运行时开销。 在创建实例时,还需要提供完整的类型名称,因为这是实际的类型名称(而泛型、未实例化的类型名称就像一种类型构造机制)。
2024-06-02 06:00:00
763
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
不过,Object Pascal RTL(Windows 平台上的 System 单元)中鲜为人知的 FindHInstance 函数会返回堆块的基地址,其中包括作为参数传递的对象,如果指针指向的是无效页,则返回 0(防止出现频率很低但极难跟踪的内存页错误)。 换句话说,从类引用指针(这是一个负偏移量,在内存中较低的位置)解引用内存位置 vmtSelfPtr 字节上的值,就可以再次获得相同的类引用指针。 一般来说,类型之间的动态转换操作,尤其是类类型之间的动态转换操作,是另一个陷阱可能的来源。
2024-06-01 06:00:00
679
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (编写健壮的应用程序 )
当构造函数引发异常时,相应的析构函数代码会自动在可能是部分初始化的对象上执行。在这种情况下,构造函数将失败,而析构函数将触发并尝试调用 FList 上的 Clear 调用,而 FList 在构造函数被调用之前就已被初始化为零。 在本章关于内存管理的最后一节,我决定列出一些略微高级的主题,以补充前面的内容。**注解:**为了遵循良好的编码实践,通常应在对象 Pascal 代码的每个构造函数中添加基类构造函数调用,即使这不是强制性的,而且额外的调用可能毫无用处(如继承 TObject.Create 时)。
2024-05-31 06:00:00
304
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第5节 (跟踪和检查内存 )
例如,在 iOS(和 macOS)上,你可以使用 Apple 的 Instruments 工具,这是一个完整的跟踪系统,可以监控物理设备上运行的应用程序的所有方面。虽然这是一个相当极端的角落情况(可能只有在一些大型内存结构中才值得这样做),但你可以覆盖这些方法来计算创建和销毁的给定类对象的数量,计算活动实例的数量,并在最后检查计数是否如预期归零。内存管理器状态显示的是已分配的各种大小的块的数量,而堆地图则相当不错,因为它描述了应用程序在系统级的内存状态。尽管如此,我们还是掌握了一些关于泄漏本身的有限信息。
2024-05-30 06:00:00
851
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第3节 (弱引用是系统托管的 )
弱引用的托管是一个非常重要的内容。换句话说,系统会在内存中保存一个弱引用列表,当对象被销毁时,系统会检查是否有任何弱引用指向该对象,如果有,系统会将实际引用赋值为 nil,即实际外部引用指针等于 nil。这意味着弱引用会产生运行时成本。 与传统的引用相比,托管的弱引用的好处是可以检查接口引用是否仍然有效(这意味着它所引用的对象已被销毁)。但这也意味着,在使用弱引用时,应始终在使用前测试它是否已被赋值。
2024-05-29 06:00:00
386
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第4节 (内存管理和接口)
在第11章中,我介绍了接口的内存管理的关键要素。与对象不同,接口是受管理且具有引用计数。如我所提到的,接口引用会增加所引用对象的引用计数,但您可以声明接口引用为弱引用以禁用引用计数(但仍然要求编译器为你管理引用),或者您可以使用unsafe修饰符完全禁用对特定引用的任何编译器支持。在这一节中,我们将深入探讨这个领域,展示一些在第11章中提供示例之外的额外示例。
2024-05-28 06:00:00
482
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第3节 (仅销毁对象一次 )
另一个问题是,如果调用对象的析构函数两次,将会导致错误。析构函数是释放对象内存的方法。 然而,当我们将对象作为按引用传递参数的方式调用一个外部函数时,该函数随后可以选择修改原始对象引用。方法),我们可以操作对象,但我们对对象引用一无所知——即我们用于调用该方法的变量的内存地址。测试将评估为True,并且在调用对象方法的行中会出现错误。虚函数是在运行时查看对象的类型来确定的,如果对象不存在,这个操作就非常危险。)的内存地址,但我们不知道引用对象的变量的内存位置,比如。,因为它是不再使用的对象的一部分。
2024-05-27 06:00:00
499
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第2节 (对象引用模型 )
要拥有两个完全独立的对象,您需要创建第二个对象并将第一个对象的数据复制到它上面(这是一项不可自动执行的操作,因为其实现细节可能因实际数据结构而异)。实际上还有一些额外的信息,例如类引用、访问对象的虚拟方法表的方法,但这超出了本章的范围(我将在第13章的“这个指针是对象引用吗?”部分中简要介绍)。一般来说,您只是复制对同一对象的引用,然后在方法或函数中访问该对象、对该对象执行操作并修改其数据,而不管参数是否作为。您可以修改原始对象,但如果将新对象赋值给参数,则此新对象与原始对象和引用原始对象的变量无关。
2024-05-26 06:00:00
376
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第3节 (内存管理技巧 )
所有者组件(通常是表单或数据模块)负责销毁它拥有的所有对象,当所有者组件被销毁时,它会自动销毁这些对象。而任何非临时对象都应该有一个所有者,或者是某个集合的一部分,或者被某个数据结构引用,由该数据结构负责在适当的时候销毁对象。 用于创建和销毁临时对象的代码通常封装在一个 try-finally 代码块中,这样即使在使用临时对象时出了问题,该对象也会被销毁。 还有一些常见的更复杂的情况,比如在需要时才创建主体(延迟初始化),或者在不再需要主体时,先于所有者销毁主体。每次创建对象时,都应同时销毁该对象。
2024-05-26 06:00:00
283
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章第1节 (全局数据、栈和堆)
堆管理器会处理所有细节,因此你只需使用底层的 GetMem 函数或调用构造函数来创建对象,系统就会为你返回一个新的内存块(可能会重复使用已丢弃的内存块)。图 13.1 显示了近 50K 全局数据(48,956 字节)的使用情况,其中包括程序及其使用的库的全局数据。Object Pascal 程序的数据(与大多数其他语言编写的程序一样)存储在三个明显不同的区域中:全局内存、栈和堆。 全局内存有时被称为静态内存,因为一旦程序加载,变量将保留在原来的位置,因此在程序的生命周期内永远不会释放这些内存。
2024-05-25 06:00:00
405
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第13章
然而,在 Object Pascal 中让情况变得稍微复杂的是,一个变量使用的内存取决于其数据类型,有些类型使用引用计数,而有些使用更传统的方法,包括 VCL 基于组件的所有权模型,以及其他一些选项,这使得内存管理成为一个复杂的主题。本章的目的就是讲述这个主题,从现代编程语言中的内存管理基础以及对象引用模型背后的概念开始。 采用这种介于两者之间的方式在于,有助于避免大多数手动内存管理的麻烦(但显然不是全部),同时又避免了自动垃圾回收带来的限制与问题(包括额外的内存分配和非确定性的资源释放)。
2024-05-24 06:00:00
323
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第4节 ( 类型别名助手)
正如我们所见,不能为相同类型定义两个助手,更不用说原生数据类型了。虽然没有明确的解决方案,但有一些可能的解决方法(除了复制内部类助手源代码并添加额外的方法)。类型别名被编译器视为全新的类型,因此它可以有自己的助手而不替换原始类型的助手。现在,鉴于这两种类型是独立的,你仍然不能将两个类助手的方法应用于同一变量,但可以将其中一组进行类型转换。我将用代码来解释这一点。 如果你声明这种新类型的变量,访问该变量将默认允许你调用新类型的助手,但你仍然可以通过转换访问 Integer 类型的助手—这段代码在。
2024-05-23 06:00:00
191
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第4节 (原生类型的记录助手)
今天的运行时库定义了一些数据类型助手在将来可能会消失,保留了使用这些助手的代码的编写方式… 但是,对于一个较小的值,你不能做同样操作,因为编译器将常量解释为最小可能的类型。 记录助手概念的进一步扩展是能够向本地(或编译器支持的原生)数据类型添加方法。 鉴于我在书的前半部分的许多示例中已经涵盖了这些助手的使用,这里无需重复它们。本节补充的是如何定义原生数据类型助手的描述。之类的类型,你实际上不需要编写上述代码,因为运行时库为大多数核心数据类型定义了一个相当全面的类助手,在。
2024-05-22 06:00:00
198
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第4节 (类助手和继承)
这个问题的部分解决方案来自于这样一个事实:你可以为一个类引入一个类助手,并为该类的子类添加一个进一步的类助手; 类助手的最大限制是,在任何时候,每个类只能有一个类助手。没有办法将类助手串联起来,也就是说,没有办法用一个类助手再进一步扩展一个已经被其他类助手扩展过的类。示例中,我还添加了用于枚举面板子控件和一个按钮子控件的代码 的子控件的代码(主要是为了测试枚举器在列表为空时能否正常工作 在列表为空时能否正常工作)。 现在,我们创建了一个如图 12.2 所示的窗体,从而可以测试在各种场景中的枚举。
2024-05-21 06:00:00
327
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第3节 ( RTL 中的类引用 )
因此,在运行 ClassRef 应用程序时,如果先放置一个按钮,然后是一个单选按钮,接着是两个编辑按钮,然后是另一个按钮,它们的名称将是 Button1、RadioButton2、Edit3、Edit4、Button5,如图所示。 请特别注意用来创建名称的代码:为了模仿 Object Pascal 的默认命名约定,我通过表达式 FControlType.ClassName 获取了类的名称,这是TObject 类的类方法。 第一个参数是一个类引用,第二个是将接收对创建的对象实例的引用的变量。
2024-05-20 20:16:37
614
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第3节(类引用)
这两个类的代码基本相同。 当一个类实现一个接口时,这个类必须实现接口中所有的方法,并且方法签名要完全相同。由于接口也继承自一个基接口(IInterface),因此实现接口的类必须全部实现接口及基接口中的所有方法。 正如我们在上面的代码中所看到的,被接口变量引用的 Object Pascal 对象是被引用计数的(除非接口类型变量被标记为弱变量或不安全变量,这将在后面解释)。 其次,无论我们使用直接赋值还是 as 语句,运行时都会做一件额外的事情:调用对象的 _AddRef 方法,增加对象的引用计数。
2024-05-19 23:59:44
687
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第2节 ( RTL中的类构造函数 )
在大多数情况下,这只是一种语法糖,因此您可能不想回头更改现有代码。然而,如果面临初始化您永远不会使用的数据结构的风险(因为从不创建该类型的类),迁移到类构造函数将提供明显的优势。在一般库中,这很明显更经常发生,您不使用其中的所有功能,而不是在应用程序代码中。 此外,你还可以隐藏普通类的构造函数,将其声明为私有,这样就很难在不遵循该模式的情况下创建该类的对象了。 在下面的实现中,我不仅利用了类数据、类方法,还利用了类析构函数进行最后的清理。类构造函数的一种非常特定的用例是在泛型类的情况下。
2024-05-18 06:00:00
201
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第2节 (类构造函数和析构函数)
换句话说,对于类的构造函数和析构函数,如果类型没有被链接,初始化代码就不是程序的一部分,也不会被执行。在传统情况下,情况恰恰相反,初始化代码甚至可能导致链接器引入某些类代码,即使这些代码实际上从未在其他地方使用过。 类构造函数负责初始化与类相关的数据,作用类似于类的初始化器,因为它们实际上并不创建任何东西。 然而,一个显著的不同是,如果将Unit 编译到程序中,initialization代码总是会被执行,但只有在实际使用类时,类构造函数和析构函数才会被链接。但是,您不能定义多个类构造函数或析构函数。
2024-05-17 06:00:00
263
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第1节 ( 类静态方法与Windows API回调)
与标准属性不同的是,类属性与类相关,并且必须使用类数据或静态类方法来实现。 在演示中,这段代码在一个定时器中执行的,它更新一个标签,因此它不需要引用任何特定的对象实例,也不是直接由任何手动操作触发的。示例中的按钮只是创建和释放一些对象,或者将一些对象保留在内存中(实际上,该程序存在一些潜在的内存泄漏)。在这个例子中,TBase 类有两个类属性,一个是 MyName,它通过类方法 GetMyName 和 SetMyName 进行读写,另一个是 DirectName,它直接读写类变量 FMyName。
2024-05-16 06:00:00
398
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章第1节 ( 类数据、Virtual类方法和隐藏的self参数)
然而,有一种特殊的语言特性可以解释这一点:与大多数其他语言不同,在Object Pascal编程语言中,类方法可以是Virtual类型。也就是说,在派生类中,你可以覆盖基类的方法,就像你可以对普通方法所做的那样。然而,这个隐藏的Self参数是指向类本身的引用,而不是类的一个实例。普通类方法与静态类方法之间的区别在于,静态类方法没有对其自身类的引用(没有指示类本身的Self参数),也不能是Virtual类型。:对Virtual类方法的支持与对Virtual构造函数的支持相关(这是一种特殊用途的类方法)。
2024-05-15 06:00:00
288
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第12章操作类(类方法和类数据)
在过去的几章中,你已经了解了 Object Pascal 语言面向对象的基础:类、对象、方法、构造函数、继承、后期绑定、接口等等。在不允许使用全局函数的面向对象编程语言中,使用类方法尤其是仅由类方法组成的类的现象更为常见。 当你在 Object Pascal语言 和其他大多数 OOP 语言中定义一个类时,你就定义了该类对象(或实例)的数据结构,以及你可以在该对象上执行的操作。有些情况下,类只由类方法组成,隐含的意思是您永远不会创建这些类的对象(您可以通过声明创建构造函数为私有)。
2024-05-14 06:00:00
262
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第3节(使用接口实现适配器模式)
虽然这只是一个非常具体的案例,但如果你仔细研究其他的设计模式,你会很容易发现,在Object Pascal中,利用接口相对于类所拥有的额外灵活性(就像在Java和C#中那样,这里仅举两个广泛使用接口的流行语言为例),可以将它们更好地实现。这样,在运行时你将得到一个新的特定类的对象。不过,现在你有了一个新组件,你必须安装它(正如我们在上一章中提到的上一章中提到的),并用这个新组件替换窗体中的现有组件。在最后一种情况,也就是我在这里即将要使用的,一个新继承的类将实现给定的接口,并将现有的行为映射到它的方法中。
2024-05-13 06:00:00
312
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第2节 (从接口引用中提取对象)
请注意,将从接口中提取的对象赋值给变量会导致引用计数问题:当接口被设置为 nil 或退出作用域时,对象实际上已被删除,引用它的变量也将失效。还要注意的是,不仅可以向原始对象的类进行类型转换,还可以向其任一基类进行类型转换(遵循类型兼容性规则)。 在过去多个Object Pascal 语言版本中,当你将一个对象赋值给一个接口变量时,是无法访问原始对象的。 在今天的Object Pascal语言中,你可以将接口引用转回先前被用来赋值的原始对象。
2024-05-12 06:00:00
374
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第2节 (接口的多态性)
给定一个普通的基类对象,我们可以调用一个虚方法,并确保调用的是正确的版本。鉴于对象与接口之间的关系可能相当复杂(一个对象可以实现多个接口,也可以间接地实现它们的基础接口),我们有必要更好地了解在这种情况下可能发生的事情。你可以向该函数传递要测试的对象或接口、目标接口(使用 GUID 或类型名称),还可以传递一个接口变量,如果函数成功执行,实际接口将被存储在该接口变量中。 您想使用接口的多态性的另一个情况是,当您有一个高级接口类型的接口数组时(也可能是对象数组,其中一些对象可能支持给定接口)。
2024-05-11 22:55:17
310
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第2节 ( 接口的委托)
与 TInterfacedObject 类相比,它在引用计数的实现(基本上是将所有引用计数委托给容器或控制器)和接口查询的实现(如果容器支持多个接口)方面有所不同。与 TInterfacedObject 相比,它在引用计数实现(基本上将所有引用计数委托给容器或控制器)和接口查询实现(如果容器支持多个接口的情况下)方面存在差异。 这个类的实现与之前的不同之处在于使用了一个特殊的基类TAggregatedObject。在下面的 TMyJumper 类中,我不想用类似的方法重复 IJumper 接口的实现。
2024-05-10 06:00:00
245
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第2节 ( 多个接口与方法别名)
不过,接口允许更动态的类型检查和类型转换,因此我们可以将一个接口转换为另一个接口,只要我们引用的对象支持这两个接口即可,编译器只能在运行时才能发现这一点。 现在我们遇到了一个问题。我们要实现的两个接口都有一个具有相同签名的 Walk 方法,那么我们如何在类中同时实现这两个方法呢? 如果为 Position 属性声明一个新的实现,我们就会为一个运动员设置两个位置,这是一种相当奇怪的情况。 其中一个接口是直接实现的,而另一个接口则委托给了内部的 FJumpImpl 对象,就像我在上一个示例中所做的那样。
2024-05-10 06:00:00
376
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第2节 (高级接口技术)
为了进一步深入探讨接口的功能,在我们研究现实世界接口的使用场景之前,有必要介绍一些接口的高级技术特性,例如类如何实现多个接口,或如何用不同名称的方法实现接口方法(以防名称冲突)。 接口属性只是一个映射到一个读取和写入方法的名字。与类不同的是,你不能将接口属性映射到字段,因为接口本身不能有任何代码。 本节的代码基于两个不同的接口 IWalker 和 IJumper,这两个接口都定义了一些方法和一个属性。 另一个重要的功能是接口可以有属性。为了演示所有这些与接口相关的高级功能,我编写了。
2024-05-09 06:00:00
287
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第1节 (Weak 和 Unsafe 类型接口引用)
现在,在你打算使用[unsafe] 属性而不增加引用计数的时候,请考虑一下,在大多数情况下,还有另一种更好的选择:使用弱(weak)引用。一个典型的情况是两个对象相互引用。事实上,在这种情况下,该对象会武断地增加其他对象的引用计数,并导致对象基本上会永远被保留在内存中(随着引用计数被设置为 1),即使对象变得不可访问也是如此。 有了这一改动,在将对象作为参数传递给 AddObjectRef 调用时,引用计数不会被修改,而是保持为 1,当变量离开作用域时,引用计数会归零,从而将对象从内存中释放出来。
2024-05-08 06:00:00
374
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第1节(混合引用中的错误)
起初,对象的引用计数为零,因为没有接口指向它。现在,在退出存储过程时,引用计数减少并归零,因此对象被销毁。换句话说,当你将 AnObj 传递给过程时,它就会被销毁,这确实有点尴尬。混合使用这两种方法会破坏对象 Pascal 所提供的引用计数机制,并可能导致极难跟踪的内存错误。在实践中,如果你决定使用接口,你可能应该只使用基于接口的变量。 在这种特定情况下,解决方案非常简单,但在许多其他情况下,却很难编写出正确的代码。 在这段代码中发生的情况是,我将一个普通对象传递给了一个期待接口的函数。
2024-05-07 06:00:00
248
原创 (delphi11最新学习资料) Object Pascal 学习笔记---第11章第1节 ( 接口的实现)
这两个类的代码基本相同。 当一个类实现一个接口时,这个类必须实现接口中所有的方法,并且方法签名要完全相同。由于接口也继承自一个基接口(IInterface),因此实现接口的类必须全部实现接口及基接口中的所有方法。 正如我们在上面的代码中所看到的,被接口变量引用的 Object Pascal 对象是被引用计数的(除非接口类型变量被标记为弱变量或不安全变量,这将在后面解释)。 其次,无论我们使用直接赋值还是 as 语句,运行时都会做一件额外的事情:调用对象的 _AddRef 方法,增加对象的引用计数。
2024-05-06 06:00:00
612
Introduction to Java Programming and Data Structures, Comprehensive Version 11e
2018-08-24
Accelerated C++.chm
2009-02-17
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人