相关疑难解决方法(0)

德尔福Singleton模式

我知道这在社区的各个地方都被讨论了很多次,但我在Delphi中找不到一个简单的单例模式实现.我在C#中有一个例子:

public sealed class Singleton {
  // Private Constructor
  Singleton( ) { }

  // Private object instantiated with private constructor
  static readonly Singleton instance = new Singleton( );

  // Public static property to get the object
  public static Singleton UniqueInstance {
    get { return instance;}
}
Run Code Online (Sandbox Code Playgroud)

我知道在Delphi中没有像这样优雅的解决方案,我看到很多关于无法在Delphi中正确隐藏构造函数的讨论(使其成为私有),因此我们需要覆盖NewInstance和FreeInstrance方法.我相信这是我在http://ibeblog.com/?p=65上找到的实现:

type
TTestClass = class
private
  class var FInstance: TTestClass;
public                              
  class function GetInstance: TTestClass;
  class destructor DestroyClass;
end;

{ TTestClass }
class destructor TTestClass.DestroyClass;
begin
  if Assigned(FInstance) then
  FInstance.Free;
end;

class …
Run Code Online (Sandbox Code Playgroud)

delphi singleton design-patterns

22
推荐指数
4
解决办法
2万
查看次数

Delphi是否在构造对象之前分配变量?

Delphi是否在对象完全构造之前分配了一个实例变量?

换句话说,给定一个变量:

var
   customer: TCustomer = nil; 
Run Code Online (Sandbox Code Playgroud)

然后我们构建一个客户并将其分配给变量:

customer := TCustomer.Create;
Run Code Online (Sandbox Code Playgroud)

是否可能customer不是nil,但不是指向完全构造TCustomer


执行延迟初始化时,这会成为一个问题:

function SacrifialCustomer: TCustomer;
begin
   if (customer = nil) then
   begin
      criticalSection.Enter;
      try
         customer := TCustomer.Create;
      finally 
         criticalSection.Leave;
      end;
   end;
   Result := customer;
end;
Run Code Online (Sandbox Code Playgroud)

错误在于:

if (customer = nil) 
Run Code Online (Sandbox Code Playgroud)

另一个线程可能会调用:

customer := TCustomer.Create;
Run Code Online (Sandbox Code Playgroud)

并且在构造发生之前为变量赋值.这会导致线程假定customer是一个有效的对象,因为该变量已分配.

这个多线程单例错误可以在Delphi(5)中发生吗?


奖金问题

Delphi 是否有可接受的,线程安全的一次性初始化设计模式?许多人通过覆盖而在德尔福实施了单身人士 ; 他们的实现将在多个线程中失败.NewInstanceFreeInstance

严格来说,我不是在回答如何实现和单例,而是懒惰初始化.虽然单例可以使用延迟初始化,但是懒惰初始化不限于单例.

更新 …

delphi lazy-loading delphi-5

5
推荐指数
3
解决办法
1395
查看次数