unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TVerctor = record X,Y,Z:Pointer; VerctorType :(vtInteger,vtDouble); public class operator Equal(const Left,Right:TVerctor): Boolean; end; TForm2 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation {$R *.dfm} { TVerctor } const verctor_offset_integer=0; verctor_offset_double=0.0001; class operator TVerctor.Equal(const Left, Right: TVerctor): Boolean; begin if (Left.VerctorType<>Right.VerctorType) then Exit(False); if (Left.VerctorType=vtInteger) then result := (abs(PInteger(Left.X)^-PInteger(Right.X)^)<=verctor_offset_integer) and (abs(PInteger(Left.Y)^-PInteger(Right.Y)^)<=verctor_offset_integer) and (abs(PInteger(Left.Z)^-PInteger(Right.Z)^)<=verctor_offset_integer) else if (Left.VerctorType=vtDouble) then Result := (abs(PDouble(Left.X)^-PDouble(Right.X)^)<=verctor_offset_double) and (abs(PDouble(Left.Y)^-PDouble(Right.Y)^)<=verctor_offset_double) and (abs(PDouble(Left.Z)^-PDouble(Right.Z)^)<=verctor_offset_double) end; procedure TForm2.Button1Click(Sender: TObject); var Verctor1,Verctor2:TVerctor; x,y,z:Double; x1,y1,z1:Double; begin x:=100.1; y:=200.2; z:=300.0001; Verctor1.X:=@x; Verctor1.Y:=@y; Verctor1.Z:=@z; Verctor1.VerctorType:=vtDouble; x1:=100.1; y1:=200.2; z1:=300.0002; Verctor2.X:=@x1; Verctor2.Y:=@y1; Verctor2.Z:=@z1; Verctor2.VerctorType:=vtDouble; if Verctor1=Verctor2 then ShowMessage('ok'); end; end.
雖然可以實現,但不是我想要的
調整後
unit Unit2; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Rtti, Types; type VectorType = (vt2D, vt3d); Vector = record case VectorType of vt2D: (X, Y: Integer); vt3d: (X1, Y2, Z2: Real;); end; TVector3<T> = record X, Y, Z: T; end; TVectorHelper = record helper for TVector3<Real> end; TVectorRec<T> = record X, Y, Z: T; class operator Equal(const Left, Right: TVectorRec<T>): Boolean; end; TVector<T> = class private FX, FY, FZ: T; public property X: T read FX Write FX; property Y: T read FY Write FY; property Z: T read FZ Write FZ; end; TVector2D = class(TVector<Integer>) public class function Equal(const Left, Right: TVector2D): Boolean; end; TVector3D = class(TVector<Double>) public class function Equal(const Left, Right: TVector3D): Boolean; end; TEntity<T> = class private FID: T; procedure SetID(const Value: T); public property ID: T read FID write SetID; end; TOrderItem = class(TEntity<Integer>) end; TOrder = class(TEntity<Integer>) end; TCustomer = class(TEntity<TGUID>) end; TForm2 = class(TForm) Button1: TButton; Button2: TButton; Button3: TButton; Button5: TButton; btnTBinaryWriter: TButton; Button4: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure btnTBinaryWriterClick(Sender: TObject); procedure Button5Click(Sender: TObject); procedure Button7Click(Sender: TObject); procedure Button8Click(Sender: TObject); procedure Button4Click(Sender: TObject); private { Private declarations } public { Public declarations } procedure test<T>(a, b: T); end; var Form2: TForm2; implementation {$R *.dfm} uses typinfo; procedure TForm2.Button1Click(Sender: TObject); var m_pCustomer: TCustomer; abc: TValueData; begin m_pCustomer := TCustomer.Create; // m_pCustomer.ID:=TGuidHelper.NewGuid; with TVector2D.Create do begin X := 1; Y := 2; ShowMessage(format('x=%d,y=%d', [X, Y])); end; abc.FAsUByte := 1; end; { TVectorRec<T> } class operator TVectorRec<T>.Equal(const Left, Right: TVectorRec<T>): Boolean; begin // ShowMessage(PTypeInfo(TypeInfo(T)).Name); case PTypeInfo(TypeInfo(T)).Kind of tkInteger: Result := (abs(PInteger(@Left.X)^ - PInteger(@Right.X)^) <= 0) and (abs(PInteger(@Left.Y)^ - PInteger(@Right.Y)^) <= 0) and (abs(PInteger(@Left.Z)^ - PInteger(@Right.Z)^) <= 0); tkFloat: Result := (abs(PDouble(@Left.X)^ - PDouble(@Right.X)^) <= 0.0005) and (abs(PDouble(@(Left.Y))^ - PDouble(@(Right.Y))^) <= 0.0005) and (abs(PDouble(@Left.Z)^ - PDouble(@Right.Z)^) <= 0.0005); //ShowMessage(FloatToStr(PDouble(@(Left.Y))^)); //ShowMessage(FloatToStr(PDouble(@(Right.Y))^)); //ShowMessage(FloatToStr(abs(PDouble(@(Left.Y))^ - PDouble(@(Right.Y))^) )); else Result := false; end; end; { TVector3D } class function TVector3D.Equal(const Left, Right: TVector3D): Boolean; begin Result := (abs(Left.X - Right.X) < 0.0001) and (abs(Left.Y - Right.Y) < 0.0001) and (abs(Left.Z - Right.Z) < 0.0001) end; { TVector2D } class function TVector2D.Equal(const Left, Right: TVector2D): Boolean; begin Result := (abs(Left.X - Right.X) < 0) and (abs(Left.Y - Right.Y) < 0) and (abs(Left.Z - Right.Z) < 0) end; { TEntity<T> } procedure TEntity<T>.SetID(const Value: T); begin FID := Value; end; procedure TForm2.test<T>(a, b: T); begin end; procedure TForm2.Button2Click(Sender: TObject); begin test<Integer>(1, 2); end; procedure TForm2.Button3Click(Sender: TObject); type TShapeList = (Rectangle, Triangle, Circle, Ellipse, Other); TFigure = record case TShapeList of Rectangle: (Height, Width: byte); Triangle: (Side1, Side2, Angle: Real); Circle: (Radius: Real); Ellipse, Other: (); end; var Figure: TFigure; begin // Figure.Height:=1; // Figure.Width:=2; Figure.Side1 := 3; Figure.Side2 := 4; Figure.Angle := 5; // Figure.Radius:=6; ShowMessage(inttostr(SizeOf(Real))); ShowMessage(inttostr(SizeOf(TFigure))); ShowMessage(format('%d,%d,%f,%f,%f,%f', [Figure.Height, Figure.Width, Figure.Side1, Figure.Side2, Figure.Angle, Figure.Radius])); end; procedure TForm2.btnTBinaryWriterClick(Sender: TObject); var bw: TBinaryWriter; begin bw := TBinaryWriter.Create('C:BinaryData.data', false, TEncoding.UTF8); try bw.Write(Caption); bw.Write(Left); bw.Write(Now); finally bw.Free; end; end; procedure TForm2.Button5Click(Sender: TObject); begin test<Integer>(1, 2); end; procedure TForm2.Button7Click(Sender: TObject); var m_pCustomer: TCustomer; abc: TValueData; begin m_pCustomer := TCustomer.Create; // m_pCustomer.ID:=TGuidHelper.NewGuid; with TVector2D.Create do begin X := 1; Y := 2; ShowMessage(format('x=%d,y=%d', [X, Y])); end; abc.FAsUByte := 1; end; procedure TForm2.Button8Click(Sender: TObject); begin test<Integer>(1, 2); end; procedure TForm2.Button4Click(Sender: TObject); var a, b: TVectorRec<Double>; begin a.X := 1.000; a.Y := 2.000; a.Z := 3; b.X := 1.0002; b.Y := 2.0001; b.Z := 3.0006; if a = b then ShowMessage('a,b一樣') else ShowMessage('a,b不一樣'); end; end.