演算子のオーバーロード(Delphi)
クラスとオブジェクト:インデックス への移動
このトピックでは、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; |
<= |
加算 |
二項 |
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 |
この表に含まれていない演算子は、クラスやレコードに定義できません。
ソース コードでは、オーバーロードされた演算子メソッドを名前で参照することはできません。特定のクラスやレコードの特定の演算子メソッドにアクセスするには、「コード例: OpOverloads(Delphi)」を参照してください。言語に用意されているクラスやレコードについては、"operator" という単語で始まるメソッドのリストに演算子識別子が含まれています(例: System.AnsiStringBase のメソッド)。上記の演算子はどれも、独自のクラスやレコードに実装できます。
コンパイラでは、以下の条件でクラスやレコードの演算子を使用します。
- 二項演算子の場合は、入力パラメータのいずれかがクラス型でなければなりません。
- 単項演算子の場合は、入力パラメータか戻り値のどちらかがクラス型でなければなりません。
- 同じシンボルを使用する論理演算子とビット演算子の場合、論理演算子はオペランドが論理型の場合にのみ使用されます。このクラス演算子のクラスは論理型でないため、もう一方のオペランドが論理型の場合にのみ論理演算子が使用されます。
演算の分配および交換のプロパティに関しては、何も仮定されていません。二項演算子の場合、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;
関連項目
- クラスとオブジェクト(Delphi)
- フィールド (Delphi)
- メソッド (Delphi)
- プロパティ(Delphi)
- ネストした型宣言
- クラス ヘルパとレコード ヘルパ(Delphi)
- クラス参照
- 例外 (Delphi)
- コード例: OpOverloads(Delphi)
- コード例: OpOverloads2(Delphi)
- System.AnsiStringBase のメソッド