http://blog.sina.com.cn/s/blog_5f8861b60102v1nl.html

Delphi 跨单元进入(访问)类的私有成员,protected ,private部分

 (2014-09-25 21:33:36)
标签: 

delphi

分类: 软件设计
转:http://hi.baidu.com/auwage/blog/item/6142231ef4f127fce1fe0bf4.html
 
作者:二娃(QQ:78493244)
 
delphi 中,同单元类,可以任意进入类成员的private至pulished部分,没有任何限制,但是对于不同的单元之间,如何进入protected ,private部分访问呢?
 
我先讲讲进入protected部分:
进入protected相对简单,现举个例子:
type
TCustomForm = class(TScrollingWinControl)
protected
FFormState: TFormState;
public
property FormState: TFormState read FFormState;
end;
TForm = class(TCustomForm);
从上面可以看出 TForm 的属性FormState是一个只读属性,正常情况下,是不能直接改变这个属性值的.但是我们可以通过一个以下来访问:
新申明一个类,这个类什么事也不做
type
TFormAccess = class(TForm);
 
procedure TForm1.Button1Click(Sender: TObject);
begin 
//这样我们就可以访问FFormState并且可以改变其值
Include(TFormAccess(Form1).FFormState, fsCreating); //注意是TFormAccess 而不是TForm
end;
 
对于private内成员跨单元相对复杂一些:
在这里我借用网上的一个贴子,上面有详细的介绍:
http://topic.csdn.net/t/20020706/20/855337.html 7楼一篇,我借花献佛了
上面的方法相对很繁琐,delphi没搞几年可能看不明白,借用《亮剑》上李云龙的句名言:云山雾绕的,那好,在这里,我介绍一种更为简单的方法,这也是我多年经验的总结
比如:
TList = class(TObject)
private
FList: PPointerList;
FCount: Integer;
FCapacity: Integer;
protected
function Get(Index: Integer): Pointer;
procedure Grow; virtual;
procedure Put(Index: Integer; Item: Pointer);
procedure Notify(Ptr: Pointer; Action: TListNotification); virtual;
procedure SetCapacity(NewCapacity: Integer);
procedure SetCount(NewCount: Integer);
public
destructor Destroy; override;
function Add(Item: Pointer): Integer;
procedure Clear; virtual;
procedure Delete(Index: Integer);
class procedure Error(const Msg: string; Data: Integer); overload; virtual;
class procedure Error(Msg: PResStringRec; Data: Integer); overload;
procedure Exchange(Index1, Index2: Integer);
function Expand: TList;
function Extract(Item: Pointer): Pointer;
function First: Pointer;
function GetEnumerator: TListEnumerator;
function IndexOf(Item: Pointer): Integer;
procedure Insert(Index: Integer; Item: Pointer);
function Last: Pointer;
procedure Move(CurIndex, NewIndex: Integer);
function Remove(Item: Pointer): Integer;
procedure Pack;
procedure Sort(Compare: TListSortCompare);
procedure Assign(ListA: TList; AOperator: TListAssignOp = laCopy; ListB: TList = nil);
property Capacity: Integer read FCapacity write SetCapacity;
property Count: Integer read FCount write SetCount;
property Items[Index: Integer]: Pointer read Get write Put; default;
property List: PPointerList read FList;
end;
对于TList的 private成员
FList: PPointerList;
FCount: Integer;
FCapacity: Integer;
这三个成员,可以通过下面方式访问
 
先声明一个类,
//注意这里,跟TList继承自同一个类.这是关键,这样保证这个新类与TList在vmt表的地址顺序是一样的
TListAccess = class(TObject)
public //注意:FList前面加一个public,还要特别注意的是,下面三个成员必需与原TList的顺序一致,否/则访问时地址会出错
FList: PPointerList;
FCount: Integer;
FCapacity: Integer;
end;
然后,我们直接这样访问了
TListAccess(List1).FList
TListAccess(List1).FCount
TListAccess(List1).FCapacity
看到没有,可以做任何事了,哈哈,够简单吧?
最后要注意的是,对于新手来说,如果你对delphi的vcl机制不熟悉,最好不要控制vcl控件的私有成员,那样风险很大的
 
 
转载自http://myvs01.blog.163.com/blog/static/1853340902011101804736983/