演算子のオーバーロード(Object Pascal)

提供: Appmethod Topics
移動先: 案内検索

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


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

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

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

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

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

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

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(Object Pascal)」(英語版)を参照してください。言語に用意されているクラスやレコードについては、"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;

関連項目

コード サンプル