演算子のオーバーロード(Delphi)

提供: RAD Studio
移動先: 案内検索

クラスとオブジェクト:インデックス への移動


このトピックでは、Delphi の演算子メソッドと、それをオーバーロードする方法について説明します。

演算子のオーバーロードについて

Delphi では、一部の関数(演算子)をレコード宣言内でオーバーロードできます。 演算子関数の名前は、ソースコード内のシンボル表現にマップされます。 たとえば、Add 演算子は、+ シンボルにマップされます。

コンパイラは、コンテキスト(つまり、呼び出しに使用されるパラメータの型および戻り値の型)が演算子関数の宣言に一致するように、適切なオーバーロードへの呼び出しを生成します。

次の表に、オーバーロード可能な Delphi 演算子を示します。

演算子 カテゴリ 宣言 シンボル マッピング

Implicit

変換

Implicit(a : type) : resultType;

implicit typecast

Explicit

変換

Explicit(a: type) : resultType;

explicit typecast

Negative

単項

Negative(a: type) : resultType;

-

Positive

単項

Positive(a: type): resultType;

+

Inc

単項

Inc(a: type) : resultType;

Inc

Dec

単項

Dec(a: type): resultType

Dec

LogicalNot

単項

LogicalNot(a: type): resultType;

not

Trunc

単項

Trunc(a: type): resultType;

Trunc

Round

単項

Round(a: type): resultType;

Round

In

集合

In(a: type; b: type) : Boolean;

in

Equal

比較

Equal(a: type; b: type) : Boolean;

=

NotEqual

比較

NotEqual(a: type; b: type): Boolean;

<>

GreaterThan

比較

GreaterThan(a: type; b: type) Boolean;

>

GreaterThanOrEqual

比較

GreaterThanOrEqual(a: type; b: type): Boolean;

>=

LessThan

比較

LessThan(a: type; b: type): Boolean;

<

LessThanOrEqual

比較

LessThanOrEqual(a: type; b: type): Boolean;

<=

Assign

二項

Assign(var Dest: type; const [ref] Src: type);

:=

加算

二項

Add(a: type; b: type): resultType;

+

減算

二項

Subtract(a: type; b: type) : resultType;

-

乗算

二項

Multiply(a: type; b: type) : resultType;

*

除算

二項

Divide(a: type; b: type) : resultType;

/

IntDivide

二項

IntDivide(a: type; b: type): resultType;

div

Modulus

二項

Modulus(a: type; b: type): resultType;

mod

LeftShift

二項

LeftShift(a: type; b: type): resultType;

shl

RightShift

二項

RightShift(a: type; b: type): resultType;

shr

LogicalAnd

二項

LogicalAnd(a: type; b: type): resultType;

and

LogicalOr

二項

LogicalOr(a: type; b: type): resultType;

or

LogicalXor

二項

LogicalXor(a: type; b: type): resultType;

xor

BitwiseAnd

二項

BitwiseAnd(a: type; b: type): resultType;

and

BitwiseOr

二項

BitwiseOr(a: type; b: type): resultType;

or

BitwiseXor

二項

BitwiseXor(a: type; b: type): resultType;

xor


この表に含まれていない演算子は、レコードに定義できません。

Overloaded operator methods cannot be referred to by name in source code. To access a specific operator method of a specific record, refer to: Code Example:OpOverloads_(Delphi). Operator identifiers are included for records in the language in the record's list of methods starting with the word "operator" (example: System.AnsiStringBase のメソッド). You can implement any of the above operators in your own records.

コンパイラでは、以下の条件でレコードの演算子を使用します。

  • 二項演算子の場合は、入力パラメータのいずれかがレコード型でなければなりません。
  • 単項演算子の場合は、入力パラメータか戻り値のどちらかがレコード型でなければなりません。
  • 同じシンボルを使用する論理演算子とビット演算子の場合、論理演算子はオペランドが論理型の場合にのみ使用されます。 このレコード演算子のレコードは論理型でないため、もう一方のオペランドが論理型の場合にのみ論理演算子が使用されます。

演算の分配および交換のプロパティに関しては、何も仮定されていません。二項演算子の場合、1 番めのパラメータは常に左オペランド、2 番めのパラメータは常に右オペランドです。結合については、かっこで明示されない限り、左から右に結合するとみなされます。

演算子メソッドは、演算に使用される型を扱えるアクセス可能なすべての演算子(継承された演算子も含む)の中から決定されます。2 つの異なる型 A と B に対する演算の場合は、型 A が B に暗黙に変換され、型 B が A に暗黙に変換されると、型が一致しません。暗黙の変換は必要な場合にのみ使用して、変換の影響を防ぐ必要があります。型 B は暗黙に型 A に変換し、型 A はそのまま(または A を暗黙に変換し、B をそのまま)にすることをお勧めします。

一般に、演算子ではオペランドを変更しません。そのかわり、パラメータを演算した結果の新しい値を返します。

オーバーロード演算子は、レコード(値型)でよく使用されます。

メモ: レコード ヘルパは、演算子のオーバーロードをサポートしません。

演算子のオーバーロードの宣言

演算子のオーバーロードは、レコードの中で、次の構文で宣言されます。

type
   typeName = record
       class operator conversionOp(a: type): resultType;
       class operator unaryOp(a: type): resultType;
       class operator comparisonOp(a: type; b: type): Boolean;
       class operator binaryOp(a: type; b: type): resultType;
   end;

オーバーロード演算子の実装にも class operator 構文を含める必要があります。

class operator typeName.conversionOp(a: type): resultType;
class operator typeName.unaryOp(a: type): resultType;
class operator typeName.comparisonOp(a: type; b: type): Boolean;
class operator typeName.binaryOp(a: type; b: type): resultType;

オーバーロード演算子の例をいくつか示します。

type
   TMyRecord = record
     class operator Add(a, b: TMyRecord): TMyRecord;      // Addition of two operands of type TMyRecord
     class operator Subtract(a, b: TMyRecord): TMyRecord; // Subtraction of type TMyRecord
     class operator Implicit(a: Integer): TMyRecord;      // Implicit conversion of an Integer to type TMyRecord
     class operator Implicit(a: TMyRecord): Integer;      // Implicit conversion of TMyRecordto Integer
     class operator Explicit(a: Double): TMyRecord;       // Explicit conversion of a Double to TMyRecord
   end;

// Example implementation of Add
class operator TMyRecord.Add(a, b: TMyRecord): TMyRecord;
begin
   // ...
end;

var
x, y: TMyRecord;
begin
   x := 12;      // Implicit conversion from an Integer
   y := x + x;   // Calls TMyRecord.Add(a, b: TMyRecord): TMyRecord
   b := b + 100; // Calls TMyRecord.Add(b, TMyRecord.Implicit(100))
end;

関連項目

コード サンプル