Модератор: Модераторы
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
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7