constructor TForm2.Create(AOwner: TComponent);
begin
  inherited;
  if (n >0) then
    raise Exception.Create('error');
  n := n+1;
end;destructor TForm2.Destory;
begin
  n := n-1;
end;procedure TForm1.Button1Click(Sender: TObject);
var
  Form:TForm2;
begin
  Form := TForm2.Create(Application);//第二次执行就会报错。
  Form.SHow;
end;

解决方案 »

  1.   

    windindance(风舞轻扬):帮主,用全局变量的方法虽然也可以,但这样不太符合面向对象的思想。有没有用类本身来实现的方法?
      

  2.   

    TO 楼上两位:
    我主要是想知道如何实现Singleton这个模式,而不是Dephi中如何用类方法
      

  3.   

    我觉得windindance(风舞轻扬)说得不错,如果要全局都看见,可以设全局变量。既然object pascal不支持static类成员,用全局变量应该没错。 何必一定要强求象其它的语言那样呢.
      

  4.   

    这里有个链接讨论Singleton模式的
    http://community.borland.com/article/0%2C1410%2C22576%2C00.html
      

  5.   

    windofsun(太阳风):
    >>这种方法只能在本单元创建类的实例,在别的单元就不行了
    谁说的?完全可以在其他单元创建。
      

  6.   

    定义一个变量为自身类型的
    如TMyclass
    public
      MyObj: TMyClass
    然后自定义构造函数
    if MyObj<>nil then
      Result:=MyObj.Create;
    类本身的Create方法不对外发布
      

  7.   

    哦,好像不行,要static变量, 不知道怎么办了
      

  8.   

    windindance(风舞轻扬):帮主,用你的方法在别的单元并不是不可以,但使用这个类的客户必须要了解这个的详细信息。否则,他怎么知道需要定义一个全局变量,以供该类的构造方法使用呢?Singleton的典型的例子就是打印机。设计模式的圣经《Design Patterns--Elements of Reusable Object-Oriented Software》在讲解什么是Singleton时就举了打印机的例子——打印机类应该只创建一个实例。但假如我们写TPrinter类,就应该完全把他封装,由这个类自己负责只创建一个实例。我们不能指望客户在用我们的打印机类的时候,预先知道需要定义一个全局变量,用来计数。就算是用户知道,也不能保证他的程序本身没有一个同名的全局变量,却有别的用途——因为我们没有把这个计数器封装到类里面。
      

  9.   

    哦,好像不行,要static变量, 不知道怎么办了
      

  10.   

    Singleton关键是要一个Static的成员变量啊
      

  11.   

    windindance(风舞轻扬): 
    我理解错你的意思了。但我还是觉得这是个不好的方法
      

  12.   

    知道了!!!!!!!!!!!1可以用DELPHI中得TStatic类, 来代替Static成员变量给分吧
      

  13.   

    TO ZengXi(var Mm: TObject):
    我主要是想讨论问题。分我一定会给的。
    你可以查看我提问的问题,到目前为止只有这一个帖子没有结帐
    还有,你说的TStatic类在哪里?我用的是Delphi 6,找不到这个类
      

  14.   

    真是笑话,研究Delphi这么多年,就没有看到过封装了什么TStatic类。
      

  15.   

    TO largewang(老王) :你是看了Delphi中TPrinter这个类吗?我举这个例子,是因为设计模式的书中举了打印机的例子。但Dephi中的TPrinter类并不完全符合Singleton这个模式,我认为。虽然我们都是通过直接用Printer来使用打印机(其实是调用Printer函数),但并不能制止我们通过构造方法生成多个TPrinter类的实例。我们完全可以在自己的代码中写:for I := 0 to PrinterCout do
    begin
      TempPrinter := TPrinter.Create;
      FList.Items[I] := TempPrinter;
    end;
      

  16.   

    不好意思,我的意思是
    自己封装这个类,关键是用指针,自己申请对象的空间,然后自己维护,
    至于singleton的实现方式,还是我上面说过的方法,
    只不过成员变量得用指针形式,共享空间
    另外,分其实无所谓
      

  17.   

    我的意思是在同一个应用内只能创建一个实例,这也是Singleton模式的核心。并不是只能在本单元内创建。重点是“一个实例”,同时也不能限制只在本单元内创建其实windindance(风舞轻扬)的方法可以实现的,nealzhao() 提到的那篇文章中也是用了这种方法。但我总是感觉用全局变量不太符合OO的思想。我自己编程时会尽量避免用全局变量
      

  18.   

    这篇文章所说的方法有两个关键:
    1、屏蔽掉原来的构造方法,而用NewInstance来创建实例。
    2、用一个全局变量来作为引用计数器。每创建一个实例,计数器就加一;每释放一个实例,计数器就减一。当计数器为0时,真正销毁实例。(类似COM组件)
      

  19.   

    TSingleton = class(TObject)
      public
        function    ISObjectExists:Boolean;
        constructor create;
      end;
    constructor  TSingleton.create;
    begin
      if ISObjectExists then
      begin
        MessageDlg('对象已存在,退出!', mtError, [mbOK], 0);
        exit;
      end
      else
      begin
        inherited;
      end;
    end;function  TSingleton.ISObjectExists:Boolean;
    var
      hMutex : THandle;
    begin
      Result := False;
      hMutex := CreateMutex(nil,False,'Singleton');
      if GetLastError= ERROR_ALREADY_EXISTS then
      begin
        Result := True;
        ReleaseMutex(hMutex);
      end;
    end;
    这样能满足要求吗?