2015-10-06 6 views
6

Delphi documentationは、Inc演算子とDec演算子をオーバーロードする可能性があることを示しています。私はそれを行う有効な方法を参照してください。 Inc演算子をオーバーロードしようとする試みがあります。いくつかの試みはエラーをコンパイルし、一部は実行時アクセス違反(Delphi XE)につながります:DelphiでInc(Dec)演算子をオーバーロードする方法は?

program OverloadInc; 

{$APPTYPE CONSOLE} 

uses 
    SysUtils; 

type 
    TMyInt = record 
    FValue: Integer; 
// class operator Inc(var A: TMyInt); DCC error E2023 
    class operator Inc(var A: TMyInt): TMyInt; 
    property Value: Integer read FValue write FValue; 
    end; 

class operator TMyInt.Inc(var A: TMyInt): TMyInt; 
begin 
    Inc(A.FValue); 
    Result:= A; 
end; 

type 
    TMyInt2 = record 
    FValue: Integer; 
    class operator Inc(A: TMyInt2): TMyInt2; 
    property Value: Integer read FValue write FValue; 
    end; 

class operator TMyInt2.Inc(A: TMyInt2): TMyInt2; 
begin 
    Result.FValue:= A.FValue + 1; 
end; 

procedure Test; 
var 
    A: TMyInt; 

begin 
    A.FValue:= 0; 
    Inc(A); 
    Writeln(A.FValue); 
end; 

procedure Test2; 
var 
    A: TMyInt2; 
    I: Integer; 

begin 
    A.FValue:= 0; 
// A:= Inc(A); DCC error E2010 
    Writeln(A.FValue); 
end; 

begin 
    try 
    Test;  // access violation 
// Test2; 
    except 
    on E: Exception do 
     Writeln(E.ClassName, ': ', E.Message); 
    end; 
    Readln; 
end. 

答えて

7

オペレータの署名が間違っています。それは次のようになります。

class operator Inc(const A: TMyInt): TMyInt; 

または

class operator Inc(A: TMyInt): TMyInt; 

あなたはvarパラメータを使用することはできません。

このプログラム

{$APPTYPE CONSOLE} 

type 
    TMyInt = record 
    FValue: Integer; 
    class operator Inc(const A: TMyInt): TMyInt; 
    property Value: Integer read FValue write FValue; 
    end; 

class operator TMyInt.Inc(const A: TMyInt): TMyInt; 
begin 
    Result.FValue := A.FValue + 1; 
end; 

procedure Test; 
var 
    A: TMyInt; 
begin 
    A.FValue := 0; 
    Inc(A); 
    Writeln(A.FValue); 
end; 

begin 
    Test; 
    Readln; 
end. 

この出力生成:ディスカッション

 
1 

これはオーバーロードかなり珍しい演算子です。使用法に関して、オペレーターはインプレース変異である。ただし、オーバーロードされると、暗黙の加数1の加算演算子のように機能します。

そこで、このライン上のコードで:

Inc(A); 

効果

A := TMyInt.Inc(A); 

に形質転換し、その後コンパイルされます。

真のインプレース突然変異のセマンティクスを維持し、この演算子に関連するコピーを避けたい場合は、その型のメソッドを使用する必要があると私は信じています。

procedure Inc; inline; 
.... 
procedure TMyInt.Inc; 
begin 
    inc(FValue); 
end; 
+1

constパラメータの突然変異が奇妙に見えますか?戻り値の関数プロトタイプも無視されますか? – kludg

+1

コールサイトでは突然変異のようですが、コンパイラは 'Inc(MyInt)'を 'MyInt:= TMyInt.Inc(MyInt);に変換します。私は 'Inc'と' Dec'を過負荷にしないだろう。 –

関連する問題