类(class function)方法的疑问.(50分)

  • 主题发起人 主题发起人 netxray
  • 开始时间 开始时间
N

netxray

Unregistered / Unconfirmed
GUEST, unregistred user!
我对class function的认识是:class function类似于c++中的static.
一直这么用,也不知对不对,今天发现class function的Result一些问题,请大家释疑:

例:
class TmyClass.function x: string;
begin
Result := Result + 'a';
end;

问: 方法第一次调用后,Result的值还是存在的吗?难道Result是static的??

多谢解答
 
Result只是表明这是返回值,并没有一个实际地方为这个函数保存这个Result,
每次调用的时候Result都应该是空的
 
但我运行时,RESULT里总是有上次的东西. [:(]
 
与C++的static不同,
如果只是声明class,哪是可以使用Self这个变量,
如果声明class static哪就没有self这个变量,<=这个应该在.net时出现。
 
那就是delphi没有把它清空了。。。我没有从文档里面发现这个特性啊。。。
你查查看文档看有没有说明
 
// 但我运行时,RESULT里总是有上次的东西.
不会吧,我试了怎么不会?

type
MyClass = class
class function DoSth: string;
end;

class function MyClass.DoSth: string;
begin
Result := Result + 'A';
end;

procedure TForm1.Button1Click(Sender: TObject);
var
my: MyClass;
begin
my := MyClass.Create;
ShowMessage(my.DoSth);
ShowMessage(my.DoSth);
ShowMessage(my.DoSth)
// 每次都只显示 A
my.Free;
end;

当然了,由于是类方法,不创建对象也应该可以使用,于是又把 Create 和 Free 两句
注释掉,结果仍然是 都只显示 A

你那里竟然出那种怪事情?呵呵。

 
应该是空的 ''
 
类方法有什么用处?请指教一二。
 
如果:
TTest=class(TObject)
private
constructor Create;
public
class function GetInstance:TTest;
end;

……

class function TTest.GetInstance:TTest;
begin
Result:=Create;
end;

var
Test1:TTest;
Test2:TTest;
begin
Test1:=TTest.GetInstance;
Test2:=TTest.GetInstance;
end;

Test1和Test2是不是TTest的同一个实例呢?



 
如果我没猜错,类的构造函数估计应该是个类方法
 
怎样才能让一个类的实例最多只有一个呢?
 
那只能利用一个全局变量了
因为Delphi没有静态成员
 
to Richard3000 :怎么让类实例只有一个。
请查阅一下 《设计模式》的 Singleton(单子)模式
或看以下url,不过是用java语言讲的,但道理一样
http://www.jdon.com/designpatterns/singleton.htm


 
MM中就有Singleton(单子)模式,点两下Mouse代码就出来了,只不过要改一下,
把const换成var,并换个位
 
Delphi中的打印机对象Printer可以认为是但实例的
Printer是个函数,每次调用,都返回同一个打印机对象
 
用java我知道怎么写。

>>testnet
MM是什么?
 
ModelMaker 6.2 在D7的盘里有。

用法
1 File-new-other-console Application
2 File-new-unit(name Unit1.pas)
3 save all
4 ModelMaker- run ModelMaker
5 ModelMaker - Conver project to ModelMaker
6 Write
uses
SysUtils;
type
A=class
public
i:integer;
end;
to Unit1.pas
7 ModelMaker- Refresh in model
8 ModelMaker - jump to ModelMaker
9 Click [Patterns] - click [Structural] -
select [A] that in Classes -
Click [apply singleton Pattern]
10 Click [unLock Code Generation] - Click [Gererate Associated Code] -Click Again
11 return Delphi IDE
12 search "const FInstance: A = nil;" //Error Code
13 use var replace const
14 Cut to implementation below
15 ModelMaker- Refresh in model
16 now you can testing,the Result is 300
var
a1,a2,a3:A;
begin
{ TODO -oUser -cConsole Main : Insert code here }
a1:=A.Instance;
a2:=A.Instance;
a3:=A.Instance;
a1.i:=100;
a2.i:=200;
a3.i:=300;
WriteLn(a1.i);
a3.ReleaseInstance;
Readln;
end.
17 let me try it
a3.ReleaseInstance;
WriteLn(a1.i)

the result is still 300 . My God leak;

18 try again
B=class
i:integer;
end;

a2.ReleaseInstance;
B.Create.i:=10;
WriteLn(a1.i);
the result is 10
****y;

19 why?
because the Delphi Memory management use Memory Pool,I think;
 
Function被调用的时候会为Result分配一个空间,这个空间直到Result失效的时候才被释放。
楼主提到的每次Result的初始值都是上次的计算结果是一种巧合,每次为Result分配的空间位置都一样。
猜想:如果在这个对象中声明一个大小不固定的变量例如:WideString,Var Array之类的,当他们的容量
发生变化后,Result分配的空间也会变化,就不会出现以上的结果。
注:永远不要使用一个没有初始化的变量。
 
同意 kusanagi,Result被分配在栈上,自动分配自动释放。
在Delphi中,所有string 型局部变量会自动初始化为'',但这条规则
对Result无效.Result的每一次初始值是随机的,和上一次一样完全是个巧合.
 
后退
顶部