Originale-mail to me for new edition

 

Constructors

 

A constructor is a special method that creates and initializes instance objects. The declaration of a constructor looks like a procedure declaration, but it begins with the word constructor. Examples:

constructor Create;

constructor Create(AOwner: TComponent);

Constructors must use the default register calling convention. Although the declaration specifies no return value, a constructor returns a reference to the object it creates or is called in.

A class can have more than one constructor, but most have only one. It is conventional to call the constructor Create.

To create an object, call the constructor method in a class type. For example,

MyObject := TMyClass.Create;

This allocates storage for the new object on the heap, sets the values of all ordinal fields to zero, assigns nil to all pointer and class-type fields, and makes all string fields empty. Other actions specified in the constructor implementation are performed next; typically, objects are initialized based on values passed as parameters to the constructor. Finally, the constructor returns a reference to the newly allocated and initialized object. The type of the returned value is the same as the class type specified in the constructor call.

If an exception is raised during execution of a constructor that was invoked on a class reference, the Destroy destructor is automatically called to destroy the unfinished object.

When a constructor is called using an object reference (rather than a class reference), it does not create an object. Instead, the constructor operates on the specified object, executing only the statements in the constructor’s implementation, and then returns a reference to the object. A constructor is typically invoked on an object reference in conjunction with the reserved word inherited to execute an inherited constructor.

Here is an example of a class type and its constructor.

type

  TShape = class(TGraphicControl)

  private

    FPen: TPen;

    FBrush: TBrush;

    procedure PenChanged(Sender: TObject);

    procedure BrushChanged(Sender: TObject);

  public

    constructor Create(Owner: TComponent); override;

    destructor Destroy; override;

    ...

  end;

constructor TShape.Create(Owner: TComponent);

begin

  inherited Create(Owner);  // Initialize inherited parts

  Width := 65;  // Change inherited properties

  Height := 65;

  FPen := TPen.Create;  // Initialize new fields

  FPen.OnChange := PenChanged;

  FBrush := TBrush.Create;

  FBrush.OnChange := BrushChanged;

end;

The first action of a constructor is usually to call an inherited constructor to initialize the object’s inherited fields. The constructor then initializes the fields introduced in the descendant class. Because a constructor always clears the storage it allocates for a new object, all fields start with a value of zero (ordinal types), nil (pointer and class types), empty (string types), or Unassigned (variants). Hence there is no need to initialize fields in a constructor’s implementation except to nonzero or nonempty values.

When invoked through a class-type identifier, a constructor declared as virtual is equivalent to a static constructor. When combined with class-reference types, however, virtual constructors allow polymorphic construction of objects, that is, construction of objects whose types aren’t known at compile time. (See Class references.)

 

Topic groups

 

See also

Calling conventions

Destructors

Exceptions: Overview

Inheritance and scope

Inherited

Method declarations and implementations

Methods: Overview

Static methods

Virtual and dynamic methods

 

 

译文

 

构造器

 

构造器是用于创建和初始化实例对象的特殊方法。构造器声明和过程声明相似,不同的是构造器的声明是以保留字constructor开始。例如:

constructor Create;

constructor Create(AOwner: TComponent);

构造器必需使用缺省的register调用约定。尽管构造器的声明没有指定返回值,但构造器总返回其创建或调用中的对象实例的引用。

一个类可以有多于一个构造器,但大多数类只有一个构造器。习惯上调用构造器Create

要创建一个对象,应调用类中的构造器方法。例如,

MyObject := TMyClass.Create;

这里,在堆中为新的对象分配了存储空间,置所有的序数域为零,赋给所有指针和类类型的域以nil值,并且置所有串类型的域为空。接下来执行构造器中指定的其他行为;典型地是,对象基于作为构造器参数传递的值被初始化。最后,构造器返回一个引用,该引用指向新的分配区域和初始化了的对象。返回值的类型域构造器调用中指定的类类型相同。

调用类引用的构造器时,如果在构造器的执行中引发异常,那么析构器Destroy会被自动调用,以销毁未完成的对象。

当用对象引用(胜于类引用)调用其构造器时,不会创建新的对象实例。这时,构造器作用于指定的对象,仅仅执行构造器实现中的语句,然后返回对象引用。作用于对象引用典型的构造器调用是与保留字inherited联合,执行继承的构造器。

下面是一个类类型及其构造器的例子。

type

  TShape = class(TGraphicControl)

  private

    FPen: TPen;

    FBrush: TBrush;

    procedure PenChanged(Sender: TObject);

    procedure BrushChanged(Sender: TObject);

  public

    constructor Create(Owner: TComponent); override;

    destructor Destroy; override;

    ...

  end;

constructor TShape.Create(Owner: TComponent);

begin

  inherited Create(Owner);  //初始化继承得到的部分

  Width := 65;  // 改变继承得到的的属性

  Height := 65;

  FPen := TPen.Create;  // 初始化新的域

  FPen.OnChange := PenChanged;

  FBrush := TBrush.Create;

  FBrush.OnChange := BrushChanged;

end;

构造器的第一个动作通常是调用继承得到的构造器以初始化继承得到的域。然后初始化在后裔类中引入的域。因为构造器总是清除为新的对象分配的存储空间,因此所有的域将以零值(序数类型)、nil(指针和类类型)、空值(串类型)或Unassigned(变体)等开始。因此,除了非零或非空的值之外,没有必要在构造器的实现中对域进行初始化。

当通过一个类类型标识符调用时,作为虚拟方法(virtual)声明的构造器等价于一个静态的构造器。不过,与类引用类型组合时,虚拟的构造器允许多态对象构造,即对象构造的类型在编译时是未知的(见类引用)。

 

主题组

 

相关主题

调用约定

析构器

异常:概述

继承和作用域

继承(Inherited

方法声明和实现

方法:概述

静态方法

虚拟方法和动态方法