unit singletonfrm;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Edit1: TEdit;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button2Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    selfptr:Tform2;
    class function GetInstancePtr:integer;
    class Function GetInstance:TForm2;
  end;var
  Form2: TForm2;implementation{$R *.dfm}
procedure TForm2.Button1Click(Sender: TObject);
begin
  hide;
end;procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  action:=cafree;
end;procedure TForm2.Button2Click(Sender: TObject);
begin
  close;
end;procedure TForm2.FormDestroy(Sender: TObject);
begin
  selfptr:=nil;
end;procedure TForm2.FormCreate(Sender: TObject);
begin
  selfptr:=self;
end;class function TForm2.GetInstancePtr: integer;
const
  isave:integer=0;
var
  pr:pointer;
  p:^integer;
  Form:TForm2;
begin
  p:=@isave;
  Form:=nil;
  if (isave<>0) then // isave保存form的地址
  begin
    result:=isave;
    Form:=pointer(isave); // 直接将数值转地址使用。
  end;  if not assigned(Form) then // 如果form未建立实例
  begin
    Form:=Tform2.Create(nil);
    p^:=integer(Form); // 现在isave的值就是form的地址啦
    result:=isave;  // 返回这个地址给调用方
  end
  else if not assigned(Form.selfptr) then // 这里怎样理解?++++++++++++++++++++
  begin                                   // 为什么要判断里面的变量?指向自己的指针又表示什么?
    Form:=Tform2.Create(nil);
    p^:=integer(Form);
    result:=isave;
  end;
end;class function TForm2.GetInstance: TForm2;
begin
  result:=pointer(GetInstancePtr);
end;end.

解决方案 »

  1.   

    不是吧,还没有人搞定感觉好像是释放对象后用assigned返回true,再通过一个指向自己的指针判断是否真的释放?
    是不是啊?给点声音,谢谢
      

  2.   

    既然看不懂,就不要用它,这种用修改const常量来保存地址的方法本来就不合理.single模式在DELPHI中实现一般用覆盖NewInstance方法实现的,加一个单元局部变量就行了
      

  3.   

    这个singleten也太难懂了,给你个简单的
    interfacetype
       Tform2= class(Tform)
         constructor Create;reintroduce;
       end;function GetSingleInstance:Tform2;implementsvar
      SingleInstance:TForm2function GetSingleInstance:Tform2
    begin
      if SingleInstance = nil then SingleInstance ;= Tform2.Create;
      result := SingleInstance;
    end;funciton Tform2.Create;
    begin
      raise Exception.Create('请用GetSingleInstance来访问.');
    end;
    initialization
        finalization
            GetSingleInstance.Free;
      

  4.   

    //用 Model Maker 操作
    1、在工程中建立一个类,
    2、Run Model Maker 
    3、Convert Project To Model
    4、View 菜单
    5、Patterns
    6、Apply SingleTon Pattern
    7、Good Luck英语有点差。//模式unit SingleTonForm;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;type
      TFormSingleTon = class(TForm)
        Edit1: TEdit;
      private
        FAOwner:TComponent;
        procedure SetAOwer(AValue:TComponent);
      protected
        class function AccessInstance(Request: Integer): TFormSingleTon;
      public
        constructor Create;
        constructor CreateInstance;
        destructor Destroy; override;
        class function Instance: TFormSingleTon;
        class procedure ReleaseInstance;
        property AOwner:TComponent read FAOwner write SetAOwer;
      end;
      
    var
      FormSingleTon: TFormSingleTon;implementation{
    ******************************** TFormSingleTon ********************************
    }procedure TFormSingleTon.SetAOwer(AValue:TComponent);
    begin
      if FAOwner<>AValue then
      begin
        FAOwner:=AValue;
      end;
    end;constructor TFormSingleTon.Create;
    begin
      inherited Create(FAOwner);
      raise Exception.CreateFmt('Access class %s through Instance only', [ClassName]);
    end;constructor TFormSingleTon.CreateInstance;
    begin
      inherited Create(FAOwner);
    end;destructor TFormSingleTon.Destroy;
    begin
      if AccessInstance(0) = Self then AccessInstance(2);
      inherited Destroy;
    end;class function TFormSingleTon.AccessInstance(Request: Integer): TFormSingleTon;
      
      {$J+}
      const FInstance: TFormSingleTon = nil;
      {$J-}
      
    begin
      case Request of
        0 : ;
        1 : if not Assigned(FInstance) then FInstance := CreateInstance;
        2 : FInstance := nil;
      else
        raise Exception.CreateFmt('Illegal request %d in AccessInstance', [Request]);
      end;
      Result := FInstance;
    end;class function TFormSingleTon.Instance: TFormSingleTon;
    begin
      Result := AccessInstance(1);
    end;class procedure TFormSingleTon.ReleaseInstance;
    begin
      AccessInstance(0).Free;
    end;{$R *.dfm}end.//调用,建议声明一个 Private 变量
    procedure TForm1.BitBtn3Click(Sender: TObject);
    var
      FFormSingleTon1,FFormSingleTon2:TFormSingleTon;
    begin
      FFormSingleTon1:=TFormSingleTon.Instance;
      FFormSingleTon2:=TFormSingleTon.Instance;
      try
        if FFormSingleTon1=FFormSingleTon2 then
        begin
          ShowMessage('The Same');
        end
        else
        begin
          ShowMessage('Differ');
        end;
        FFormSingleTon1.Show;
        FFormSingleTon2.Show;
      finally
        //FFormSingleTon1.ReleaseInstance;
        //FFormSingleTon2.ReleaseInstance;
      end;
    end;
       FFormSingleTon1.ReleaseInstance;
       FFormSingleTon2.ReleaseInstance;   这两句不要注释。//bug 有点,没设计好,自己弄下就有了,很容易
      

  5.   

    谢谢,我想看知道为什么上面那代码要这样写?
    下面的代码是覆盖newinstance.出现"a component named form2 alerday exist",再按一下出现地址错。是不是这样的步骤?
    1.Newinstance分配内存
    2.initInstance设定执行框架那么什么地方弹出那个提示?为什么会这样?unit Unit2;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm2 = class(TForm)
      private
        { Private declarations }
      public
        { Public declarations }
        class function NewInstance: TObject; override;
      end;implementation{$R *.dfm}{ TForm2 }class function TForm2.NewInstance: TObject;
    const
      Instance: TObject = nil;
    begin
      if Instance = nil then
      begin
        Result := inherited NewInstance;
        Instance := Result;
      end
      else begin
        Result := Instance;
      end;
    end;end.
      

  6.   

    1,外部调用函数:
    也就是说,想调用这个 窗体,
    创建用Instance
    释放用ReleaseInstance
        class function Instance: TFormSingleTon;
        class procedure ReleaseInstance;
    其余的函数内部使用。2,
    ShowMessage('The Same');
    表明创建的窗体的地址相同,也就是说只有一个窗口。
    这就是 SingleTon。3,其余的看刘艺的 Delphi 模式编程。