谁能用Delphi7实现单例模式(100)

放飞

Unregistered / Unconfirmed
GUEST, unregistred user!
嘿嘿,我通常也是和 wzwcn 兄一样干的
 
A

Avalon

Unregistered / Unconfirmed
GUEST, unregistred user!
to wzwcn你那方法至少用到了全局变量这在楼主眼里不是完美的单例 最多算是个山寨的单例罢了to abszo你的方法不错 但有个前提 使用者不知道CreateNew 否则你的这个单例就完美了但是 比如这样unit Unit1;interfaceuses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;type TForm1 = class(TForm) Button1: TButton;
procedure Button1Click(Sender: TObject);
private { Private declarations } public { Public declarations } end;
TSingletonTest = class private constructor CreateNew;
public constructor Create;
class function GetInstance(GetFlag: Boolean = true): TSingletonTest;
procedure Show();
end;
var Form1: TForm1;implementation{$R *.dfm}{ TSingletonTest }constructor TSingletonTest.Create;
begin
raise Exception.Create('do not use create of '+ClassName);
end;
constructor TSingletonTest.CreateNew;
begin
;
end;
class function TSingletonTest.GetInstance(GetFlag: Boolean = true): TSingletonTest;{$J+}const inst: TSingletonTest = nil;{$J-}begin
if GetFlag then
begin
if not Assigned(inst) then
begin
inst := TSingletonTest.CreateNew;
end;
end else
begin
if Assigned(inst) then
begin
inst.Free;
inst := nil;
end;
end;
Result := inst;
end;
procedure TSingletonTest.Show;
begin
ShowMessage('address:'+IntToStr(Integer(self)));
end;
procedure TForm1.Button1Click(Sender: TObject);var a:TSingletonTest;
a2:TSingletonTest;
begin
a := TSingletonTest.CreateNew;
a.Show;
a2 := TSingletonTest.CreateNew;
a2.Show;
end;
end.
我依然得到了2个实例 用D7去实现绝对java式的单例 或者说完美的单例 窃以为 不可能
 
M

muhx

Unregistered / Unconfirmed
GUEST, unregistred user!
不讨论这个问题了,既然Delphi2006已经给出了解决方案,我们就不纠缠语法了大家有没有好的议题大家一起讨论,我想把我的分都散尽
 
A

Avalon

Unregistered / Unconfirmed
GUEST, unregistred user!
唉 前几天发帖问 如何得到网卡启动的持续时间 有人回帖说那个秒表这坛子是越来越水 肯像楼主一样探讨问题的帖子是越来越罕见了
 
A

autumn

Unregistered / Unconfirmed
GUEST, unregistred user!
上面各位大大的codes好像都没有处理destrory的情况,如果这样调用就有问题了:procedure CallOne();var obj: TSingleton;
begin
obj := TSingleton.GetInstance();
//Do something for obj FreeAndNil(obj);
end;
procedure CallSecond();
begin
TSingleton.GetInstance(TRUE).DoSomething();//maybe errorend;
finalization TSingleton.GetInstance(FALSE);//free instance //maybe error当然,可以用额外的代码处理上述情况。但是我觉得单件只是一个概念,具体情况具体分析。就好像需要一个刀子杀鸡,不用费12小时做一把面面俱到的牛刀,只要满足要求,花个2小时搞个鸡刀出来就可以了。
 
A

autumn

Unregistered / Unconfirmed
GUEST, unregistred user!
贴一个以前参考dxExpressGrid写的代码unit SingletonUtils;interfaceuses SysUtils;type TSingleton = class(TObject) protected FNeedFree: Boolean;
constructor CreateNew();
virtual;
class function funcInstance(const flag: BYTE): TSingleton;
public constructor Create;
class function NewInstance(): TObject;
override;
procedure FreeInstance();
override;
class function GetInstance(): TSingleton;
end;
implementationconst SINGLETON_GET = 1;
SINGLETON_NIL = 2;
SINGLETON_FREE = 3;
STR_ERR_CREATE = 'TSingleton不支持的调用约定,请使用GetInstance.';{ TSingleton }constructor TSingleton.Create;
begin
raise exception.Create(STR_ERR_CREATE);
end;
constructor TSingleton.CreateNew;
begin
end;
procedure TSingleton.FreeInstance;
begin
inherited;
if FNeedFree then
funcInstance(SINGLETON_NIL);
end;
class function TSingleton.funcInstance(const flag: BYTE): TSingleton;const inst: TSingleton = nil;
begin
case flag of SINGLETON_GET: if not Assigned(inst) then
begin
inst := TSingleton.CreateNew();
inst.FNeedFree := TRUE;
end;
SINGLETON_NIL: inst := nil;
SINGLETON_FREE: if Assigned(inst) then
FreeAndNil(inst);
end;
Result := inst;
end;
class function TSingleton.GetInstance: TSingleton;
begin
Result := funcInstance(SINGLETON_GET);
end;
class function TSingleton.NewInstance: TObject;
begin
Result := inherited NewInstance;
TSingleton(Result).FNeedFree := FALSE;
end;
initialization ;finalization TSingleton.funcInstance(SINGLETON_FREE);
end.
 
M

muhx

Unregistered / Unconfirmed
GUEST, unregistred user!
多人接受答案了。
 
顶部