如何实现这样效果?
如何实现这样效果?
如何实现这样效果?
解决方案 »
- :) 大家给出个主意吧,跟贴有分哦...... :)
- Parameters.ParamByName的问题!
- 怎么让自己定义的文件在打开时自动运行自己的程序并将文件内容在程序中读出来?(没你想的那么简单!!)(在线等...)
- 关于统计的问题,很简单噢!!快来帮我!!!!!
- 急!急!急!初学Delphi,请各位大虾提供一些Delphi书籍和源代码资源
- 郁闷,去一家公司应聘明明是软件维护,怎奈要求去做开发(兼维护,调试等等)要求过分,给的钱又少,感觉如同受骗!散分!!
- ★★★★★用Delphi的ado连接sql 2000桌面版的困难★★★★★
- Access violation at address 00661017 in module 'a.exe' ,write of address.这种错误是如何引起的,如何解决?
- delphi写"网络摄像机"监控软件的问题。。有那位兄弟能帮忙解决,谢谢
- 请问这样的程序如何做:主窗口显示后运行某一过程,而且只运行一次
- 问斑竹一个关于信誉分的问题
- 怎样创建这样的一个视图?
你的方法在Delphi中实现不了( 一家之辞, 我是这样认为的或许哪们高手可以实现)
private
a:integer;
public
procedure Seta(b:integer);
function Geta:integer;
end;
/////////
function TA.Geta:integer;
begin
result:=a;
end;procedure TA.Seta(b:integer);
begin
a:=b;
end;
/////////////////
var
c:TA;
i:PInteger;
begin
c:=TA.create;
c.Seta(1);
i:= Pinteger(Integer(c) +$04);
i^:=2;
SHowmessage(IntTOStr(c.Geta));
end;
2 你将var后的代码封装到另外的类,就实现了你“友类”的目的,但是TA的定义改动后,代码不一定有效
3 这是直接对对象的内存块进行操作,虽然能够实现,但是非常危险,强烈不推荐!
定义一个类
TDxf = Class(TObject)
private
FDxfObjcet: TDxfObject;
public
ReadDxf(FileName: String);
end; TDxfObject = Class(TObject)
private
X: Integer
functin Read();
end;现在TDxf和TDxfObject不在同一个Unit中
在ReadDxf中要设置 FDxfObject.X的值,而且要调用FDxfObject.Read
procedure TDxf.ReadX():integer;//读取FDxfObjcet.X
begin
result:=Pinteger(Integer(FDxfObjcet) +$04)^;
end;
FDxfObjcet.Read函数的调用同样可以通过函数指针实现
2 如果你是想在设计期间使用
procedure TDxf.ReadX():integer;//读取FDxfObjcet.X
begin
result:=FDxfObjcet.X;
end;
这样的代码,除非你是在同一个单元!
procedure TDxf.ReadX():integer;//读取FDxfObjcet.X
begin
result:=Pinteger(Integer(FDxfObjcet) +$04)^;
end;
FDxfObjcet.Read函数的调用同样可以通过函数指针实现
2 如果你是想在设计期间使用
procedure TDxf.ReadX():integer;//读取FDxfObjcet.X
begin
result:=FDxfObjcet.X;
end;
这样的代码,除非你是在同一个单元!
直接访问内存怎么能算友元,说到指针我更愿意用c或者win32汇编(笑),在他们中更本没有类的概念吧
所谓的“友元”,应该不是人为的算法或方法,应该是高级语言提供的一种语言特性。
同时学过c++与delphi pascal的都应该比较过这两种语言的特性吧
至少目前为止,在我查阅的国内外资料中,好像没有delphi pascal提供友元特性这一说法
事实上,友元本身也一定程度破坏了封装性,大概也只有c++想的出来吧
delphi提供在同一单元的类可以互相任意访问毫无限制已经很开放了,但确实还算不上支持友元
用指针或取地址,那是完全操作内存的方法,只要语言支持这种数据类型,在任何语言上都能实现你们所谓的“友元”的想法(这是我的想法)。事实上不要说友元了,直接操作内存,连windows api都能改(金山词霸大家没忘?), 这并不能说xx语言提供了修改windows api的特性?(笑)
如果各位有任何资料说明“delphi pascal”中确实提供支持"友元"特性,请提供强有力证明
谢谢
DELPHI应该没有友元这个概念
是C++中过来的但是在一个单元里就可以做到这个效果有些东西讨论多了,没有什么意思
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我不喜欢友元,它破坏了封装性,不要也罢。
>>>不能这么说,用时,你就感觉到它的好处
跨单元访问某个类的私有变量,好像很多人都知道直接用指针去取,恐怕都是看了一篇《如何
跨单元访问私有变量》的文章学的,那种方法不太好,其实最简单的是用一个record模拟在其它单元中声明的类的内存结构,或者最彻底的方法是在本单元做一个模拟类,可以非常方便和
安全地跨单元访问私有变量。基本上,可以实现跨单元访问私有变量,保护的方法和变量,至于如何访问私有的方法我不大清楚。
还是多去大富翁的object pascle专区,相比,这里的……,不用我说了。
//类所在的单元
unit Unit2;interfacetype
TA = class
private
FNum1: string;
FNum2: Integer;
FNum3: string;
public
constructor Create; virtual;
end; TB = class(TA)
private
FNote1: string;
FNote2: Integer;
public
constructor Create; override;
end;
implementation{ TA }constructor TA.Create;
begin
FNum1 := 'FNum1';
FNum2 := 1;
FNum3 := 'FNum3';
end;{ TB }constructor TB.Create;
begin
inherited;
FNote1 := 'FNote1';
FNote2 := 2;
end;end.//访问的单元
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TRefRecord = record //TA
FNum1: string;
FNum2: Integer;
FNum3: string;
end;
PRefRecord = ^TRefRecord; TRefRecord2 = record //TB
FNote1: string;
FNote2: Integer;
end;
PRefRecord2 = ^TRefRecord2; TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;implementationuses Unit2;{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);
var
pt: PRefRecord;
a: TA;
begin
try
a := TA.Create;
pt := Pointer(Integer(a) + TObject.InstanceSize);
ShowMessage(pt^.FNum3);
finally
a.Free;
end;end;procedure TForm1.Button2Click(Sender: TObject);
var
pt2: PRefRecord2;
b: TB;
begin
try
b := TB.Create;
pt2 := Pointer(Integer(B) + TA.InstanceSize);
ShowMessage(pt2.FNote1);
finally
B.Free;
end;end;end.另外一种更简单的方法事模拟类,原理与模拟纪录相同,不再列出。
至于如何访问私有方法,不太清楚,我实现不了。
只能变通解决
说白了,这种方法也是绕过了类封装约束进行访问的,不过这种方法的确较那篇文章中提到的方法简单!另外想请教一个细节问题InstanceSize是对象方法,而不是类方法,通过类直接调用以为着什么?
计算TA时加上TObject.InstanceSize是因为TA的父类是TObject,在堆中每个类都包含它的所有父类,这里是通过计算步长找到TA开始的位置,字段是按照其声明的顺序排列的,所以,通过计算获得TA开始的地址,然后就可以访问了,你可以把TObject.InstanceSize换成4,一样通过,(头4个字节->VMT),至于TB,则加上TA的偏移,同样的道理。我上面说过,可以通过模拟类来实现,让Delphi帮我们计算步长,比模拟纪录更简单。
1、如果两个类在同一单元,就很简单了,相互间可以访问,^_^;
2、如果不在同一单元,想相互访问也不难:
假设有两个单元:
unit unit1;type
TClass1 = class(TObject)
..
..
end;unit unit2;type
TClass2 = class(TObject)
..
..
end;要想在unit2中访问TClass1中的的成员,可以在unit2中新声明一个类
type
TClass3 = Class(TClass1);
这样,通过TClass3就可以访问TClass1了。
因此,还是不能算真正友元。
但要做到访问private不太可能吧.并且Delphi没有提供这方面的操作.它只支持在同一个Pas文件中友元类.
在同一个Pas文件中声明的类全是友元类.