unit uSingletonDerivado;

interface

uses
  uSingleton, SysUtils, DateUtils, Windows, dialogs;

type


  TObjetoUnicoDerivado = class(TObjetoUnico)
  private
    class var FObjetoUnico: TObjetoUnicoDerivado;
    class var  FContador: Integer;
    class function GetContador: integer; static;
    class function GetObjetoUnico: TObjetoUnicoDerivado;  static;
  public
    constructor Create; reintroduce;
    destructor Destroy; override;
    function GetDataHora: string; override;

    class property ObjetoUnico: TObjetoUnicoDerivado  read GetObjetoUnico;
    class property Contador: integer read GetContador;

  end;

procedure VerificaObjetoUnicoDerivadoCriado;

implementation



procedure VerificaObjetoUnicoDerivadoCriado;
begin
  if (TObjetoUnicoDerivado.FContador >= 1) and (TObjetoUnicoDerivado.FObjetoUnico <> nil) then
    ShowMessage('=========== verificação ===========' + #13#10 +
    'Nome da classe: ' + TObjetoUnicoDerivado.FObjetoUnico.ClassName+ #13#10 +
    'Hora de Criação pelo método: ' + TObjetoUnicoDerivado.FObjetoUnico.GetDataHora + #13#10 +
    'Hora de Criação pela propriedade: ' + TObjetoUnicoDerivado.FObjetoUnico.DataHora + #13#10 +
    'Endereço na memória: ' + IntToStr(Integer(TObjetoUnicoDerivado.FObjetoUnico))
  );
end;


{ TObjetoUnicoDerivado }


constructor TObjetoUnicoDerivado.Create;
begin
    if (FContador = 0) and (FObjetoUnico = nil) then
    begin
      InterlockedIncrement(FContador);
      DataHora := FormatDateTime('yyyy-mm-dd hh:nn:ss', now);
    end
    else
      raise Exception.Create('Ei! Não use esse constructor, use o CreateUnico!');
end;


destructor TObjetoUnicoDerivado.Destroy;
begin
  FObjetoUnico := nil;
  InterlockedDecrement(FContador);
end;

class function TObjetoUnicoDerivado.GetContador: integer;
begin
  Result := FContador;
end;



function TObjetoUnicoDerivado.GetDataHora: string;
begin
  Result := 'acréscimo ' + inherited GetDataHora;
end;


class function TObjetoUnicoDerivado.GetObjetoUnico: TObjetoUnicoDerivado;
begin
  if (FContador = 0) and (FObjetoUnico = nil) then
    FObjetoUnico := TObjetoUnicoDerivado.Create;
  Result := FObjetoUnico;
end;


initialization

finalization
  //aqui há um exemplo de como o objeto único pode ser destruido
  TObjetoUnicoDerivado.FObjetoUnico.Free;

end.
