[All]
Delphi 7以降の言語およびコンパイラの新機能
投稿者: : Tomohiro Takahashi
概要: Delphi 7以降にリリースされたDelphiに搭載された、数多くの新しい言語機能を解説します。
Delphi 7以降の言語およびコンパイラの新機能 |
|
インライン化
|
ルーチンにinline指令を指定できるようになりました。 これは、コンパイラに対して、そのルーチンを実際に呼び出す代わりに、呼び出し側にそのルーチンを含むコードを出力するよう指示します。
|
|
演算子のオーバーロード
|
Delphiでは、いくつかの関数または演算子をレコード宣言内でオーバーロードできます。
TMyClass = class
class operator Add(a, b: TMyClass): TMyClass;
class operator Subtract(a, b: TMyClass): TMyclass;
class operator Implicit(a: Integer): TMyClass;
class operator Implicit(a: TMyClass): Integer;
class operator Explicit(a: Double): TMyClass;
end;
TMyClass.Add(a, b: TMyClass): TMyClass;
begin
...
end;
var
x, y: TMyClass
begin
x := 12;
y := x + x;
b := b + 100;
end;
|
|
クラスヘルパー
|
クラスヘルパーは、別のクラスに関連付けられて、そのクラス(またはその派生クラス)のコンテキスト下において使用される追加のメソッドおよびプロパティを導入するための型です。クラスヘルパーは、継承を使用することなくクラスを拡張する手法です。クラスヘルパーは単に、コンパイラが識別子を解決する際に使用するスコープを広げます。クラスヘルパーを宣言する場合は、ヘルパー名とヘルパーによって拡張するクラス名を指定します。クラスヘルパーは、拡張クラスを使用できる場所ならどこでも使用できます。コンパイラの解決スコープは,元のクラスとクラスヘルパーを合わせたものになります。クラスヘルパーはクラスを拡張する手法を提供しますが、新規にコードを開発する際に使用する設計手法とは考えないでください。クラスヘルパーは、言語とプラットフォームRTLとを結合するという本来の目的でのみ使用してください
type
TMyClass = class
procedure MyProc;
function MyFunc: Integer;
end;
...
procedure TMyClass.MyProc;
var
X: Integer;
begin
X := MyFunc;
end;
function TMyClass.MyFunc: Integer;
begin
...
end;
...
type
TMyClassHelper = class helper for TMyClass
procedure HelloWorld;
function MyFunc: Integer;
end;
...
procedure TMyClassHelper.HelloWorld;
begin
WriteLn(Self.ClassName);
end;
function TMyClassHelper.MyFunc: Integer;
begin
...
end;
...
var
X: TMyClass;
begin
X := TMyClass.Create;
X.MyProc;
X.HelloWorld;
X.MyFunc;
end;
|
|
strict private
|
privateキーワードは実際には同一ユニット内のクラス間に「フレンド」な関係を作成します。 strict private宣言は、同一ユニット内のクラスはもちろんのこと、他のクラスからは見えない、真にプライベートなフィールドを作成します。
|
|
strict protected
|
strict private宣言と同様に、strict protectedは、それを宣言したクラスおよび派生クラスからしか見えない、真にプロテクテッドなメンバーを作成します。
|
|
メソッドを持つレコード
|
レコードは、フィールドに加えて、プロパティ/メソッド(コンストラクタも含む)/クラスプロパティ/クラスメソッド/クラスフィールド/ネストした型を持てるようになりました。
type
TMyRecord = record
type
TInnerColorType = Integer;
var
Red: Integer;
class var
Blue: Integer;
procedure printRed();
constructor Create(val: Integer);
property RedProperty: TInnerColorType read Red write Red;
class property BlueProp: TInnerColorType read Blue write Blue;
end;
constructor TMyRecord.Create(val: Integer);
begin
Red := val;
end;
procedure TMyRecord.printRed;
begin
writeln('Red: ', Red);
end;
|
|
abstractクラス
|
メソッドだけでなく、クラスもabstractを宣言できるようになりました。
type
TAbstractClass = class abstract
procedure SomeProcedure;
end;
|
|
sealedクラス
|
sealedが指定されたクラスは継承して拡張するはできません。
type
TAbstractClass = class sealed
procedure SomeProcedure;
end;
|
|
クラス定数
|
クラスは、クラス定数を持てるようになりました。これは、クラスのインスタンスごとではなく、クラスそのものに付随する定数です。
type
TClassWithConstant = class
public
const SomeConst = 'This is a class constant';
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
ShowMessage(TClassWithConstant.SomeConst);
end;
|
|
クラス型
|
クラスに、そのクラス内でのみ利用可能な型を宣言できるようになりました。
type
TClassWithClassType = class
private
type
TRecordWithinAClass = record
SomeField: string;
end;
public
class var
RecordWithinAClass: TRecordWithinAClass;
end;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
TClassWithClassType.RecordWithinAClass.SomeField := 'This is a field of a class type declaration';
ShowMessage(TClassWithClassType.RecordWithinAClass.SomeField);
end;
|
|
クラスフィールド
|
クラスは、クラスのインスタンスごとではなく、クラス単体で利用可能なクラス変数を持てるようになりました。「クラス型」の例を参照してください。
|
|
クラスプロパティ
|
クラスは、クラスのインスタンスに対してではなく、クラスへの参照に対するプロパティであるクラスプロパティを持てるようになりました。 クラスプロパティへのアクセッサは、クラスメソッドかクラス変数でなければなりません。 「静的なクラスメソッド」の例を参照してください。
|
|
ネストしたクラス
|
クラス宣言の中で、ネストした型宣言が可能になりました。これは、概念的に関連する型をまとめたり、名前の競合を回避するための手段になります。
type
TOuterClass = class
strict private
MyField: Integer;
public
type
TInnerClass = class
public
MyInnerField: Integer;
procedure InnerProc;
end;
procedure OuterProc;
end;
procedure TOuterClass.TInnerClass.InnerProc;
begin
...
end;
|
|
finalメソッド
|
オーバーライドしたvirtualメソッドにfinal指令を指定できるようになりました。これにより、派生クラスがそのメソッドをオーバーライドするのを防ぎます。
TAbstractClass = classabstract
public
procedure Bar; virtual;
end;
TSealedClass = class sealed(TAbstractClass)
public
procedure Bar; override;
end;
TFinalMethodClass = class(TAbstractClass)
public
procedure Bar; override; final;
end;
|
|
sealedメソッド
|
sealedを指定したクラスは継承による拡張はできません。「finalメソッド」の例を参照してください。
|
|
静的なクラスメソッド
|
クラスは静的なクラスメソッドを持てるようになりました。例えば、クラス型を使って呼び出し可能なメソッドです。静的なクラスメソッドは、オブジェクトの参照無しにアクセス可能です。クラスの通常のメソッドとは違い、静的なクラスメソッドはSelfパラメータを有しません。あらゆるインスタンスメンバにアクセスすることもできません(クラスフィールド/クラスプロパティ/クラスメソッドにはアクセス可能です)。クラスのメソッドとは違い、静的なクラスメソッドはvirtual宣言することもできません。
type
TMyClass = class
strict private
class var
FX: Integer;
strict protected
class function GetX: Integer; static;
class procedure SetX(val: Integer); static;
public
class property X: Integer read GetX write SetX;
class procedure StatProc(s: String); static;
end;
TMyClass.X := 17;
TMyClass.StatProc('Hello');
|
|
for-inループ
|
Delphi 2007 for Win32は、コンテナに対する for-element-in-collection 形式の繰り返しをサポートします。次に、コンパイラが認識するコンテナ繰り返しパターンを示します。
for Element in ArrayExpr do Stmt;
for Element in StringExpr do Stmt;
for Element in SetExpr do Stmt;
for Element in CollectionExpr do Stmt;
|