我应该何时在Delphi中使用增强记录类型而不是类?

mjn*_*mjn 15 delphi oop class record delphi-2006

Delphi 2006引入了新的记录功能,使其更加"面向对象".

在哪种情况下,记录类型更适合于设计而不是类类型?使用这些记录类型有哪些优势?

Too*_*the 15

你有记录,对象和类.

自turbo pascal 1以来可以获得记录.它们是轻量级的,能够具有属性和方法,但它们不支持继承.返回记录的函数存在一些问题.如果这些记录有方法,这有时会产生内部错误:

type
  TRec = record 
    function Method1: Integer;
  end;

function Func: TRec;


procedure Test;
var
  x : TRec;

begin
  Func.Method1; // Sometimes crashes the compiler
  // Circumvention:
  x := Func;
  x.Method1; // Works
end;
Run Code Online (Sandbox Code Playgroud)

如果我是正确的话,用turbo pascal 5引入物体.然后他们为paso提供了OO的方法.随着Delphi的引入,它们或多或少被弃用了,但你仍然可以使用它们.对象可以实现接口.

Delphi 1引入了类,功能最多.它们实现接口并支持继承.但是每个类变量都是一个隐藏指针.这意味着需要在堆上创建类.幸运的是,这个过程大多是隐藏的.

下面是三个表之间的差异表.我添加了完成界面.

                  |Class|Object|Record|Interface|
------------------|-----------------------------|
Are pointers?     |  y  |  n   |  n   |    y    |
Inheritance       |  y  |  y   |  n   |    y    |
Helpers           |  y  |  n   |  y   |    n    |
Impl. Interface   |  y  |  y   |  n   |    -    |
Visibility        |  y  |  y   |  n   |    n    |
Method            |  y  |  y   |  y   |    y    |
Fields            |  y  |  y   |  y   |    n    | 
Properties        |  y  |  y   |  y   |    y    |
Consts            |  y  |  y   |  y   |    n    |
Types             |  y  |  y   |  y   |    n    |
Variants          |  n  |  n   |  y   |    n    |
Virtual           |  y  |  n   |  y   |    -    |
------------------|-----------------------------|
Run Code Online (Sandbox Code Playgroud)


Hen*_*man 8

我认为Delphi 8和2005中也提供了这些功能.

主要指南:如果您有疑问,请使用课程.

对于其余部分,您必须了解主要区别:类对象始终通过引用使用,并通过调用构造函数创建.

记录的内存管理和分配与基本类型(即整数,双精度)相同.这意味着它们按值传递给方法(除非使用var).此外,您不需要Free记录,这就是它们支持运算符重载的原因.但没有继承或虚拟方法等.新记录可以有一个构造函数,但它的使用是一种可选的.

使用记录的主要领域和标准:

  • 处理来自Win32 API的结构时

  • 当类型没有标识时(因为赋值意味着复制)

  • 当实例不是太大时(复制大记录变得昂贵)

  • 构建值类型时,其行为应模仿数值类型.例子是DateTime,复数,向量等.然后运算符重载是一个很好的功能,但不要把它作为决定因素.

效率方面,不要过度:

  • 对于经常放入数组的较小类型.

最后,使用类或记录的规则并没有真正改变早期版本的Delphi.


Mas*_*ler 6

除了其他答案(运算符重载,轻量值类型)之外,最好使枚举器记录而不是类.由于它们是在堆栈上分配的,因此不需要构造和销毁它们,这也消除了对编译器放置在类类型枚举器周围的隐藏try..finally块的需要.

有关详细信息,请参阅http://hallvards.blogspot.com/2007/10/more-fun-with-enumerators.html.