2015-10-06 15 views
6

Delphi documentation nói rằng có thể quá tải các nhà khai thác Inc và tháng 12; Tôi thấy không có cách nào hợp lệ để làm điều đó. Đây là những nỗ lực để quá tải toán tử Inc; một số nỗ lực dẫn đến lỗi biên dịch, một số lần vi phạm truy cập thời gian chạy (Delphi XE):Làm thế nào để quá tải các nhà khai thác Inc (Dec) trong Delphi?

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. 

Trả lời

7

Chữ ký của toán tử là sai. Nó nên là:

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

hoặc

class operator Inc(A: TMyInt): TMyInt; 

Bạn không thể sử dụng một tham số var.

Chương trình này

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

sản xuất sản lượng này:

 
1 

Thảo luận

Đây là một nhà điều hành khá bất thường khi quá tải. Về mặt sử dụng, toán tử là một đột biến tại chỗ. Tuy nhiên, khi quá tải, nó hoạt động giống như một toán tử cộng với một phần bổ sung ngầm định của một toán tử.

Vì vậy, trong đoạn code trên dòng này:

Inc(A); 

được hiệu quả chuyển đổi thành

A := TMyInt.Inc(A); 

và sau đó biên soạn.

Nếu bạn muốn duy trì đúng ngữ nghĩa đột biến tại chỗ và tránh sao chép được liên kết với toán tử này, thì tôi tin rằng bạn cần sử dụng phương pháp loại.

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

Đột biến tham số const có vẻ lạ, phải không? Ngoài ra các nguyên mẫu chức năng với giá trị trả về được bỏ qua? – kludg

+1

Dường như đột biến tại trang cuộc gọi, nhưng trình biên dịch dịch 'Inc (MyInt)' thành 'MyInt: = TMyInt.Inc (MyInt); 'Có nó rất lạ. Tôi sẽ không quá tải 'Inc' và' Dec'. –

Các vấn đề liên quan