Модератор: Модераторы


Cheb писал(а):После этого все классы у тебя становятся менеджед, со счётчиком ссылок, и компилятор сам заботится чтобы экземпляр класса удалился когда на него протухнет последняя ссылка.
{
Sergey Bodrov (serbod@gmail.com) 2016
}
unit WeakRefs;
interface
type
  IWeakRef = interface
    ['{4C4419E1-7ADB-47A4-826A-61E03FBB4C84}']
    procedure _Clean;
    function IsAlive: Boolean;
    function GetOwner(): TObject;
  end;
  { Слабая ссылка, которая хранит ссылку на какой-то объект и висит в памяти,
    пока ее кто-то использует. Позволяет проверять, жив ли объект или нет. }
  TWeakRef = class(TInterfacedObject, IWeakRef)
  private
    FOwner: TObject;
  public
    constructor Create(AOwner: TObject); virtual;
    procedure _Clean;
    function IsAlive: Boolean;
    function GetOwner(): TObject;
  end;
  TWeakObject = class(TObject)
  protected
    FWeakRef: IWeakRef;
    function GetWeakRef(): IWeakRef; virtual;
  public
    procedure BeforeDestruction(); override;
    property WeakRef: IWeakRef read GetWeakRef;
  end;
implementation
{ TWeakRef }
constructor TWeakRef.Create(AOwner: TObject);
begin
  FOwner := AOwner;
end;
procedure TWeakRef._Clean();
begin
  FOwner := nil;
end;
function TWeakRef.GetOwner(): TObject;
begin
  Result := FOwner;
end;
function TWeakRef.IsAlive(): Boolean;
begin
  Result := Assigned(FOwner);
end;
{ TWeakObject }
procedure TWeakObject.BeforeDestruction;
begin
  if Assigned(FWeakRef) then
    FWeakRef._Clean();
  inherited;
end;
function TWeakObject.GetWeakRef: IWeakRef;
begin
  if FWeakRef = nil then
  begin
    FWeakRef := TWeakRef.Create(Self);
  end;
  Result := FWeakRef;
end;
end.type
  { некий ключ, у которого может быть владелец, который может вдруг исчезнуть }
  TKey = class(TObject)
  private
    FPersonWeakRef: IWeakRef;
    function GetPerson: TPerson;
    procedure SetPerson(const Value: TPerson);
  public
    { владелец ключа }
    property Person: TPerson read GetPerson write SetPerson;
  end;
function TKey.GetPerson: TPerson;
begin
  if Assigned(FPersonWeakRef) and FPersonWeakRef.IsAlive then
    Result := TPerson(FPersonWeakRef.GetOwner())
  else
    Result := nil;
end;
procedure TKey.SetPerson(const Value: TPerson);
begin
  if Assigned(Value) then
    FPersonWeakRef := Value.WeakRef
  else
    FPersonWeakRef := nil;
end;


Лекс Айрин писал(а):а цена вопроса?

serbod писал(а):Но увы, нормального механизма "слабых" указателей на класс не завезли.

ЧетоТам(@ЧетоТам1,@ЧетоТам2);zub писал(а):ЧетоТам(@ЧетоТам1,@ЧетоТам2);
передача указателей на данные - самое стремное решение, использовать такое нужно если по другому ну совсем никак.
при использовании @ компилятор умывает руки из контроля типов параметров, всё это ложится на плечи "програмиста" и приводит к неизбежным глюкам

zub писал(а):модификаторы

Да, интерфейсы к сишным библиотекам такое требуют постоянно. Приходится выкручиваться. Но в любых собственно паскалевских программах за использовать подобного надо отрубать руки по самую задницу.vitaly_l писал(а):А как тогда быть, если такого: ЧетоТам(@ЧетоТам1,@ЧетоТам2); - обращения требуют системные библиотеки?


Снег Север писал(а):Да, интерфейсы к сишным библиотекам такое требуют постоянно. Приходится выкручиваться. Но в любых собственно паскалевских программах за использовать подобного надо отрубать руки по самую задницу.vitaly_l писал(а):А как тогда быть, если такого: ЧетоТам(@ЧетоТам1,@ЧетоТам2); - обращения требуют системные библиотеки?
Лекс Айрин писал(а):В случае серьезной работы, использование объектов очень сильно замедляет работу программ... иногда на порядки. Пример -- компонент TMemo, который, при всей его примитивности очень уж тормозит при более-менее больших текстах (((

Увы, тип class - это тупой указатель, без влияния на счетчик ссылок. Для переменных типа class счетчик ссылок не работает. Нужен тип переменной interface (которой присвоен экземпляр class), а это несколько ограничивает удобство пользования.
Пример -- компонент TMemo, который, при всей его примитивности очень уж тормозит
Но в любых собственно паскалевских программах за использовать подобного надо отрубать руки по самую задницу.
const и var вполне годятся для сишных библиотек.

Вернуться в Free Pascal Compiler
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1