随笔 - 2047  文章 - 71 评论 - 10629 trackbacks - 253

提示1: 点击 标题 可进入首页;   提示2: 从搜索引擎中搜索 万一 可迅速找到这里.
昵称:万一
园龄:4年3个月
荣誉:推荐博客
粉丝:349
关注:34

随笔分类(2499)

随笔档案(2051)

积分与排名

  • 积分 - 4148339
  • 排名 - 4

最新评论


当我把一个"结构体"在类中当做属性后, 在实用中可以直接读取结构体成员, 但不能直接写入...

下面是由此引发的小练习:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure Button5Click(Sender: TObject);
  end;

  TMyClass = class
  strict private
    FPos: TPoint;
    procedure SetPos(const Value: TPoint);
  public
    property Pos: TPoint read FPos write SetPos; //属性 Pos 对应一个点结构
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyClass }

procedure TMyClass.SetPos(const Value: TPoint);
begin
  FPos := Value;
end;


{测试}

procedure TForm1.Button1Click(Sender: TObject);
var
  obj: TMyClass;
begin
  obj := TMyClass.Create;
  ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]); //可以直接访问结构中的元素
//  obj.Pos.X := 11;  //但不能直接给结构中的元素赋值
//  obj.Pos.Y := 22;
  obj.Free;
end;

//变通一
procedure TForm1.Button2Click(Sender: TObject);
var
  obj: TMyClass;
begin
  obj := TMyClass.Create;
  obj.Pos := Point(22,33); //
  ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]);
  obj.Free;
end;

//变通二
procedure TForm1.Button3Click(Sender: TObject);
var
  obj: TMyClass;
  pt: TPoint;
begin
  obj := TMyClass.Create;
  pt.X := 33;
  pt.Y := 44;
  obj.Pos := pt;
  ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]);
  obj.Free;
end;

//变通三(假如属性的 get 不是方法)
procedure TForm1.Button4Click(Sender: TObject);
var
  obj: TMyClass;
  p: PPoint;
begin
  obj := TMyClass.Create;
  p := Addr(obj.Pos);
  p.X := 44;
  p.Y := 55;
  ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]);
  obj.Free;
end;

//变通四(假如属性的 get 不是方法)
procedure TForm1.Button5Click(Sender: TObject);
var
  obj: TMyClass;
begin
  obj := TMyClass.Create;
  PPoint(Addr(obj.Pos)).X := 55;
  PPoint(Addr(obj.Pos)).Y := 66;
  ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]);
  obj.Free;
end;

end.


练习二:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  end;

  TMyClass = class
  private
    FPos: TPoint;
    function GetPos: TPoint;
    procedure SetPos(const Value: TPoint);
    function GetXY(const Index: Integer): Integer;
    procedure SetXY(const Index, Value: Integer);
  public
    property Pos: TPoint read GetPos write SetPos;
    property X: Integer index 0 read GetXY write SetXY;
    property Y: Integer index 1 read GetXY write SetXY;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyClass }

function TMyClass.GetPos: TPoint;
begin
  Result := FPos;
end;

procedure TMyClass.SetPos(const Value: TPoint);
begin
  FPos := Value;
end;

function TMyClass.GetXY(const Index: Integer): Integer;
begin
  Result := 0;
  case Index of
    0: Result := FPos.X;
    1: Result := FPos.Y;
  end;
end;

procedure TMyClass.SetXY(const Index, Value: Integer);
begin
  case Index of
    0: FPos.X := Value;
    1: FPos.Y := Value;
  end;
end;

{测试}
procedure TForm1.FormCreate(Sender: TObject);
var
  obj: TMyClass;
begin
  obj := TMyClass.Create;
  obj.X := 11;
  obj.Y := 22;
  ShowMessageFmt('%d, %d', [obj.Pos.X, obj.Pos.Y]);
  obj.Free;
end;

end.

posted on 2012-01-05 16:56 万一 阅读(680) 评论(4) 编辑 收藏

FeedBack:
#1楼 2012-02-04 10:53 好小爱新      
如果用C++Builder则可以把GetPos的返回值设为引用:)这样就可以直接使用了,示例如下:
class TMyClass
{
TPoint FPos;
public:
TPoint &GetPos(){return FPos;}
__property TPoint Pos={read=GetPos,write=FPos};
};
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
TMyClass lgs;
lgs.Pos.x=123;
lgs.Pos.y=456;
ShowMessage(Format("(%d,%d)",ARRAYOFCONST((lgs.Pos.x,lgs.Pos.y))));
return 0;
}
//---------------------------------------------------------------------------

 回复 引用 查看   
#2楼 2012-02-04 10:56 好小爱新      
回复一个带格式化的:)
如果用C++Builder则可以把GetPos的返回值设为引用:)这样就可以直接使用了,不知道Delphi有没有类似的:)示例如下:
class TMyClass
{
	TPoint FPos;
public:
	TPoint &GetPos(){return FPos;}
	__property TPoint Pos={read=GetPos,write=FPos};
};
#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
	TMyClass lgs;
	lgs.Pos.x=123;
	lgs.Pos.y=456;
	ShowMessage(Format("(%d,%d)",ARRAYOFCONST((lgs.Pos.x,lgs.Pos.y))));
	return 0;
}
//---------------------------------------------------------------------------

 回复 引用 查看   
#3楼 2012-02-08 03:46 melice      
delphi自己的处理方法。
1.把tpoint换成类
2.把pos的x和y做成property访问

其实也就是说,设计的时候应当避免这种情况。

 回复 引用 查看   
#4楼 2012-02-11 18:27 Bach      
最近正好遇到这个问题,又正好溜达到老师的博文,受教了。我的解决办法只跟练习一一样,还没有深入到练习二,应该多向老师学习啊,钻研啊!
 回复 引用 查看