2015-10-06 15 views
6

Delphi documentation, Inc ve Dec operatörlerinin aşırı yüklenmesinin mümkün olduğunu söylüyor; Bunu yapmak için geçerli bir yol göremiyorum. İşte Inc operatörünü aşırı yüklemeye çalışır;Delphi'de Inc (Dec) operatörleri nasıl yüklenir?

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. 

cevap

7

operatörün imzası yanlıştır: Bazı girişimler bazı erişim ihlali (XE Delphi) çalışma süresiyle, derleme hataları neden olur. Olmalıdır:

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

veya

class operator Inc(A: TMyInt): TMyInt; 

Bir var parametresini kullanamazsınız.

 
1 

Tartışma

aşırı olduğunda bu oldukça sıradışı operatörüdür:

Bu program

{$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. 

bu çıktıyı üretir. Kullanım açısından operatör yerinde bir mutasyondur. Ancak, aşırı yüklendiğinde, örtülü bir eklenti olan bir ek işleç gibi çalışır.

Yani, bu çizginin üzerinde kodunda:

Inc(A); 

etkili bir

A := TMyInt.Inc(A); 

dönüşmüş ve daha sonra derlenmektedir.

Doğru yerinde mutasyon semantiklerini korumak ve bu işleçle ilişkili kopyalamayı önlemek istiyorsanız, türün yöntemini kullanmanız gerektiğine inanıyorum.

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

const parametresinin mutasyonu garip görünüyor, değil mi? Ayrıca, geri dönüş değeri göz ardı edilmek üzere işlev prototipi mi? – kludg

+1

Arama sitesinde mutasyona benziyor, ancak derleyici 'Inc (MyInt)' i 'MyInt: = TMyInt.Inc (MyInt) 'ye çeviriyor;' Evet çok garip. Ben 'Inc' ve' Dec' aşırı yüklemez. –