发分啦:一个简单的例子谈Delphi类的静态局部变量 (300分)

  • 主题发起人 叮叮当当
  • 开始时间

叮叮当当

Unregistered / Unconfirmed
GUEST, unregistred user!
在Delphi5中直接用const来定义静态局部变量,在Delphi6中则可以使用const和{$J+}开关来办到。但是这样的静态变量如果定义在类方法中,那么这个类所创建的对象里的静态变量都是共享的。

我写了一个简单的例程如下:

在Delphi里New->Application,再New->Unit,贴入MyObj类的代码如下:
unit Unit2;

interface

type
TMyObj = class
public
procedure ShowID;
end;

implementation

uses Dialogs, SysUtils;

procedure TMyObj.ShowID;
{$J+}
const
I: Integer = 0;
{$J-}
begin
ShowMessage(IntToStr(I));
Inc(I);
end;

end.


然后回到Unit1,在Interface段添加对Unit2的引用,在Form1上放2个Button。
为Form1的OnCreate、OnClose事件以及两个Button的OnClick事件添写处理代码,最终使Unit1的代码变成如下:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Unit2;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormClose(Sender: TObject
var Action: TCloseAction);
private
{ Private declarations }
OBJ1, OBJ2: TMyObj;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
OBJ1 := TMyObj.Create;
OBJ2 := TMyObj.Create;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
OBJ1.ShowID;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
OBJ2.ShowID;
end;

procedure TForm1.FormClose(Sender: TObject
var Action: TCloseAction);
begin
OBJ1.Free;
OBJ2.Free;
end;

end.

现在按F9运行程序,点击Button1->显示数字0->点击Button1->显示数字1->点击Button2->显示数字2,这表示OBJ1和OBJ2的静态局部变量I在整个类中是共享的。

[red]好了,我的问题是怎么才能使对象中的静态局部变量变为独立的?就是每个对象都拥有自己独立的静态局部变量![/red][blue](不要用定义类的私有全局变量的方法!因为那不符合oop)[/blue]
 
太多了!
头都看晕了!
帮你UP一下
 
有毛病!静态变量的意义就是不依附于任何实例存在,怎么可能是独立的???

除非不用静态变量。
 
To: 一个过客
我有很多过程要避免重复调用(重入),我的处理方法通常如下:

procedure TMyObj.Function1;
{$J+}
const AlreadyIn: Boolean = False;
{$J-}
begin
if AlraedyIn then Exit;
AlreadyIn := True;
.... // do something
AlreadyIn := False;
end;

写到这里你应该知道如果 Function1 是一个类的方法的话,那么如果这个类创建了多个对象会出什么问题吧。
 
呵呵,所谓静态变量就是类的共享变量,所有对象在同一进程内都共享,这是他的特性,
没办法改啊
 
作为私有变量算了,方便,简单
 
大家帮我想个办法啊[:(]
 
To: 来如风
用类的私有全局变量代替局部静态变量当然也可以解决问题,但这不是一种良好的编程习惯,还会给查错、日后的代码维护带来很多困难。
 
静态变量就这个样子,你没有办法改变的,
不过对于查错、日后的代码维护我想也没有什么困难的,都是在构造函数中赋初值的,这和静态变量有区别吗?
我个人认为如果你在程序中要是改变静态变量值的话那这个静态变量其实就是一个赋了初始值的一般变量而已
 
To: 来如风
你看我上面给 一个过客 的程序代码,如果我有很多过程要避免重复调用(重入),放弃静态变量而用私有全局变量,那我难道要定义n个AlreadyIn的全局变量?AlreadyIn1、AlreadyIn2、AlreadyIn3、……?象这样可读性好吗?!
 
定义私有变量,然后在相应属性的get中取那个全局变量。以后可以改,子类继承以后还可以重载。
 
不明白你的意思,每个对象只有自己的私有对象AlreadyIn啊,一个就够了啊,
不过还是对你程序的流程不太明白,稍微说清楚一点呢,就是说举个稍微实际一点的例子,
例如说你的AlreadyIn是干嘛用的?每次怎么用,
 
叮叮当当 的意思是不是要避免两个实例(同一类别)同时调用同一成员方法?
 
To: xeen
不是,实际例子就象我上面给 一个过客 的代码,如下:

procedure TMyObj.Function1;
{$J+}
const AlreadyIn: Boolean = False;
{$J-}
begin
if AlraedyIn then Exit;
AlreadyIn := True;
.... // do something
AlreadyIn := False;
end;

Function1是一个控件的事件(比如串行通信的接收事件),会被重复调用,我在Function1内部设置了一个静态局部变量AlreadyIn以防止重入。而当我的TMyObj被创建多个实例的时候这个AlreadyIn就变得不可靠了,因为每个实例都可以更改它的值。而如果将AlreadyIn作为类私有全局变量的话,这显然就有违代码规则了,因为AlreadyIn只在Function1中有意义,而且我还要担心别的函数中的静态变量会和它重名或更改它的值。
 
用对象自身的一个变量或者属性都可以实现的啊,
你的静态变量也不是在一直改变值吗?
你说要建立好多个AlreadyIn我 一直没有搞明白是什么意思
 
你的需求是互相矛盾的,试想又要与特等的实例相联系,又要是静态的,这可能吗?
我是没听说哪门语言里有这种东西.
静态区的东西是在编译的时候就分配内存空间,实际就在我们的Exe或Dll文件里就有
它的位置了,在PE文件启动的时候被映射到内存,它的生命周期直至我们程序的始终.

类的实例(在Delphi中)都分配在自由存储区(堆)上。需要动态创建、动态释放.
所以你防止成员方法重入还要与特定实例相联系,必须把标识变量定义成类的成员
变量.

或者把同步的工作留给调用者完成,Windows提供了不少同步线程的API



 
To: xeen
我以前是用VB的,那时我用static定义静态变量就没有这种问题啊,不过VB6里面倒是没有类的概念罢了。

唉。。除了用类的成员变量外,还有人有更好的解决办法么?
 
其实现在C++都不推荐用静态变量,这样不方便管理,应该可以用
更好的办法,比如局部成员变量来代替
 
最好别用,有别的方法
 
用私有变量,然后用public过程修改值不可以啊,这正是面向对象的开发语言所提倡的啊
 

Similar threads

D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
711
import
I
顶部