在多个类中使用全局变量(30分)

只要包含这个类的单元就行了。
合理好安排这个全局类的创建和释放,稍微注意一下就可以了
我建议你把这个类的作为定义这个类的单元的一个全局变量
位置在:
var
变量:变量类型
implementation
 
>>要让它全局使用还得定义一个全局的类变量,说白了还是定义全局变量

逻辑更混乱了。说到底,每个form不都是全局的? delphi本身就是这样的。
想不要任何一个额外的全局变量? 用java吧!
 
还是有些糊涂 :(,
打个比方说吧,代码如下:
TA = class
private
FA:integer;
end;

TB = class
public
procedure proc;
end;

procedure TB.proc;
begin
//我想在这引用FA,该怎么做?
end;
 
他们如果在一个单元里可以用,如果不是,你可以这样
TA = class
private
FA:integer;
procedure setFA(const value:integer);
public
property A:integer read FA write SetFA;
end;
通过这个类的属性来访问FA,
 
>>我想在这引用FA,该怎么做?

引用是什么概念? 仅仅是read还是write? 如果是只读得,你可以在TA里面做一个方法
专门访问FA:

TA = class
private
FA:integer;
public
function GetFA:integer;
end;
这样一来,私有成员还是私有的,但是可以访问了。
 
嗯,感觉两位虽然代码不一样,但原理是一样的,都是让私有变量“转换”成公有属性(函数),
然后通过这个属性(函数)来引用(读/写)私有变量。
这样理解对不对?
 
靠!我贴的时候无忌的还没有呢!怎么我落后了!

你的理解是对的
 
是这样的!
还有一般来说一个单元里的两个类可以互相访问他们之间的
私有变量。
 
不过,如果向无忌那样把读/写都开放出来,那还不如直接把FA public得了
 
放在public?那TA的对象实例不就直接可以引用FA了吗?
在对象中直接引用类的变量好象不符合OOP的封装吧?
 
实用为先,如果你的这个变量有范围之类的控制,用我的办法,如果
没这个考虑,简单起见,当PUBLIC也是可以的
 
如果你的私有成员“需要”被外界“读”,并且“写”,那么它还是一个私有成员吗?
我理解的封装,并不仅仅是用读写函数把私有成员隐藏起来这样的。
 
当然这个类的变量被外界读写的时候,你如果放到Public里面了,
如果这个变量的范围有限制,那你怎么控制???用读写函数
一般来说是为了控制写的时机和范围。
 
那倒是。
 
不好意思,半路跑了 :) 因为我忽然想起我的代码不是这样的!回去看了一下我的代码,
现在重新整理我的问题,简化代码如下(抱歉,长了点):
unit unit2
interface
uses classes,dialogs;
type
TA = class
public
FS: TStringList
//本来FS应该放在private中的,但为了简化程序,暂且放在public中
  constructor Create;
destructor Destroy
override;
end;

TB = class
private
FB: TA
//如果不这样声明一个对象,那么根本不能引用TA的FS,我这样做是不是错了?
public
procedure proc_B;
end;

TC = class
private
FC: TA;
public
procedure proc_C;
end;

var
var_s: TStringList
//全局变量

implementation

procedure TC.proc_C;
begin
FC := TA.Create;
FC.FS.Add('c')
//虽然FS可以引用,但它已经和FB.FS完全不同了!
         //对FC.FS的操作并不意味着FB.FS也会改变!
 FC.Free;
if Assigned(var_s) then
var_s.Add('c')
//但全局变量就不同!当var_s改变item时,所有类中对var_s的引用都会改变!
end;

procedure TB.proc_B;
begin
FB := TA.Create;
FB.FS.Add('b')
//如果先调用proc_C,再调用proc_B,那么会得到两个不同的对象,而它们的FS属性是完全不同的!
  FB.Free;

if Assigned(var_s) then
var_s.Add('b')
//如果先调用proc_C,再调用proc_B,那么var_s就会有两个item
end;

constructor TA.Create;
begin
FS := TStringList.Create;
var_s := TStringList.Create;
end;

destructor TB.Destroy;
begin
FS.Free;
var_s.Free;
inherited;
end
 

我想知道怎样不使用全局变量而达到var_s的效果?
 
************* 原文 ********************
var_s.Add('c')
//但全局变量就不同!当var_s改变item时,所有类中对var_s的引用都不会改变!
***************************************
请改正,应该是 “都会改变!”

另外,只要能够在某处,使 TA 只创建一次,在 TB 、TC 中使用指针引入这个已经创建
了的 TA 对象,犹如 var 引参一样,就可以达到你的目的。需要说明的是,这只是一个
技巧,而不是 OOP 原则,OOP 原则还是需要象 张无忌 和 一个过客 说的那样去做。
 
小雨哥:
  谢谢提醒,呵呵,一时手快打错了!
已经改正了。
 
TA只创建一次?可是TB和TC都要引用TA啊,该怎么让TA只创建一次就能让TB和TC都能使用?
能详细说说吗?ego不是普通的笨,还请高手多多指点。
 
高手都走了还是代码太长了?或者是这个问题不值得讨论?
 
呵呵,高手都过年去了,还是我来回答你把。

首先,你在delphi里面强求舍去全局变量是不现实的。只要不是Java/C#这样的
完全面向对象的语言,总是会存在全局变量。如果你看VCL的源代码,里面也有大量
的全局变量,这不是能力问题,而是语言的限制。我觉得学OO这个东西不要太形而
上学,要领会OO的本质,而不是刻意追求形式。

我看了你的代码,你的意思是不是就是不想要var_s这样一个全局变量? 其实我
平时写程序,遇到这种情况也是用全局变量的,包括还有很多全局函数(公共函数)
等,这样的确不是很OO,但是用起来很方便,而且并没有对整个系统的OO结构造成
很大的破坏,所以我一直这样用。

不过如果你用Java,就会有点困惑,因为java里面是没有地方放你的全局变量和
公共函数的。我一般是为该程序专门写一个模块类,把所有的全局变量和函数都作为
模块类的“类变量”和“类方法”,这样引用的时候其实和全局变量效果一样,而且
不用实例化该类(因为是“类变量”);

但是delphi里面仅支持“类方法”,并不支持“类变量”。如果照搬java的方法,
就需要把该模块类实例化一个全局对象,然后引用该对象的成员(代码见下)。但是
这样一来就又出现一个全局对象了。。。。所以我说在delphi里面这样钻牛角尖是
没有意义的。

type
TGlobalClass = class
public
Lst:TStringlist;
constructor create( lst:=tstringlist.create)

destructor destroy( lst.free);
end;
TB = class
....
end;

TC = class
....
end;
var
Global: TGlobalClass
//全局变量
implementation

//引用的时候用Global.Lst.add(...);

不过我还是不明白,你前面说的TGlobalClass的Lst成员一定要是private,为什么?


最后 祝你春节愉快!
 
顶部