Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
Реализовал (по работе) механизм, который позволяет автоматически уничтожать объекты. Избавляет от необходимости использования try..finally для удаления объектов.
Пример кода:
procedure Test;
var
  h: TSmartHolder;
  L: TList;
  ini: TIniFile;
  sl: TStrings;
begin
  L := h.CreateList(); // Создание типового объекта
  // далее используем переменную L как обычно

  h.RegObj(ini, TIniFile.Create('myfile.ini')); // Создание произвольного объекта
  // далее используем переменную ini как обычно

  sl := h.RegObj(TStringList.Create) as TStrings; // Создание произвольного объекта
end;


TSmartHolder - это простейший рекорд с единственным полем (интерфейсная ссылка).
Соответственно, все объекты будут уничтожены, как только интерфейсная ссылка будет обнулена, т.е. при выходе рекорда из области видимости.
Работает, начиная с Delphi 2007.
На мой взгляд, штука очень удобная.

Если есть интерес, я могу это оформить на своём аккаунте в гитхабе в виде отдельного модуля.
С другой стороны, не исключаю, что вариантов реализации данного велосипеда уже множество (но мне до сих пор не попадалось) :)
29 мар 21, 12:33    [22301368]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1825
Умный указатель через reference to function интереснее... там даже подсказчик кода работает и синтаксис использования не меняется, кроме объявления...
29 мар 21, 13:59    [22301415]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
X-Cite
Умный указатель через reference to function интереснее... там даже подсказчик кода работает и синтаксис использования не меняется, кроме объявления...


Где посмотреть на это?
29 мар 21, 14:03    [22301420]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12789
DmSer
TSmartHolder - это простейший рекорд с единственным полем (интерфейсная ссылка).
Тогда ты ее постоянно перезаписываешь. Или там у тебя какой-то IInterfacedList?
DmSer
На мой взгляд, штука очень удобная.
Если изменить требование D2007 на D2009, то RegObj можно объявить дженерик методом и уйти от каста
function RegObj<T: class>(const AVal: T): T;

DmSer
На мой взгляд, штука очень удобная.
Иногда последовательность уничтожения объектов важна.
29 мар 21, 14:07    [22301424]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
rgreat
Member

Откуда:
Сообщений: 6653
ИМХО это не красиво и не очень удобно.

Не надо связываться с интерфейсами, где это явно не требуется.

В конце концов если сильно хочется - используй рекорды. Благо там теперь и конструктор с деструктором есть.
29 мар 21, 14:15    [22301430]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
Тогда ты ее постоянно перезаписываешь. Или там у тебя какой-то IInterfacedList?


Там объект, который хранит список зарегистрированных объектов в TList. Объект реализует интерфейс. В рекорде хранится интерфейсная ссылка на этот объект.

Если изменить требование D2007 на D2009, то RegObj можно объявить дженерик методом и уйти от каста


Можно, как вариант.

Иногда последовательность уничтожения объектов важна


Разные ситуации бывают, конечно.
29 мар 21, 14:20    [22301432]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
rgreat
ИМХО это не красиво и не очень удобно.

Не надо связываться с интерфейсами, где это явно не требуется.

В конце концов если сильно хочется - используй рекорды. Благо там теперь и конструктор с деструктором есть.


В коде нет явной работы с интерфейсами (см. пример в начале). Всё спрятано в методы рекорда. Интерфейсная ссылка объявлена как private.
29 мар 21, 14:23    [22301438]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1825
  ISmartPointer<T: class> = reference to function: T;

  TSmartPointer<T: class> = class(TInterfacedObject, ISmartPointer<T>)
  strict private
    FObject: T;
    function Invoke: T; inline;
  public
    constructor Create(const aObject: T);
    destructor Destroy; override;
  end;


{ TSmartPointer<T> }

function TSmartPointer<T>.Invoke: T;
begin
  Exit(FObject);
end;

constructor TSmartPointer<T>.Create(const aObject: T);
begin
  FObject := aObject;
end;

destructor TSmartPointer<T>.Destroy;
begin
  FreeAndNil(FObject);
  inherited Destroy();
end;

procedure TForm2.Button1Click(Sender: TObject);
var
  x: ISmartPointer<TForm2>;
begin
  x := TSmartPointer<TForm2>.Create(TForm2.Create(nil));
  x.Caption := '123';
  x.ShowModal();
end;


В последних версиях сломали правда CodeInsight...
29 мар 21, 14:27    [22301442]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
Использование RegObj выглядит не очень красиво. К сожалению. Тут ничего не поделаешь.
Но такой код смотрится вполне прилично:

var L := h.CreateStringList();


можно так:
var L := TStringList.Create();
h.RegObj(L);


У меня в коде есть классы, которые я чаще всего использую (назовём их "типовые классы"). Для них сделал функции создания объекта (CreateStringList, CreateList и т.п.). Иногда добавляю новые функции по мере необходимости. Но это свой фирменный велосипед :)
29 мар 21, 14:31    [22301445]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
alekcvp
Member

Откуда:
Сообщений: 2792
X-Cite,

destructor TSmartPointer<T>.Destroy;
begin
  FreeAndNil(FObject);
  inherited Destroy();
end;

Зачем?.. Почему не Free?

Ну и каждое обращение к переменной - вызов функции, ну такое себе. Хотя надо смотреть как компилятор вызов заинлайнит.

Сообщение было отредактировано: 29 мар 21, 14:26
29 мар 21, 14:31    [22301446]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1825
alekcvp,

Да все равно... Можно и Free
Ну это уже проблемы компилятора, если он не сможет заинлайнить))) За сомнительное удобство, не из коробки, надо платить...
29 мар 21, 14:41    [22301456]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 5101
alekcvp
Хотя надо смотреть как компилятор вызов заинлайнит.

Это же интерфейс, откуда там инлайну взяться. Однако, прикольное колдунство :)

Сообщение было отредактировано: 29 мар 21, 14:38
29 мар 21, 14:45    [22301459]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
var
x: ISmartPointer<TForm2>;
begin
x := TSmartPointer<TForm2>.Create(TForm2.Create(nil));


Не заметил особого преимущества по сравнению с

var
  x: TForm2;
  h: TSmartHolder;
begin
  x := h.RegObj(TForm2.Create(nil)) as TForm2;


А пытаться понять как работает ISmartPointer - ещё сложнее, чем разобраться с фильмом Довод :)
29 мар 21, 15:07    [22301469]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 5101
DmSer
Не заметил особого преимущества

Если правильно помню, эту запись:
x := TSmartPointer<TForm2>.Create(TForm2.Create(nil));

можно сократить до:
x := TSmartPointer.Create(TForm2.Create(nil));

или вообще создание смартпоинтера завернуть в функцию, например:
x := Auto(TForm2.Create(nil));
29 мар 21, 15:17    [22301473]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 12789
Kazantsev Alexey
можно сократить до:
Нельзя.
1. TSmartPointer и TSmartPointer<T> - это разные типы.
2. Можно было бы писать
x := TSmartPointer<>.Create(TForm2.Create(nil));
но это вам не джава и автовывод типов сюда не завезли
Kazantsev Alexey
или вообще создание смартпоинтера завернуть в функцию,
Нельзя. Дженерик-функций не бывает
29 мар 21, 15:28    [22301484]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
Kazantsev Alexey
Member

Откуда:
Сообщений: 5101
_Vasilisk_
Нельзя.
1. TSmartPointer и TSmartPointer<T> - это разные типы.

Верно, только не специализированных дженериков не бывает.

_Vasilisk_
но это вам не джава и автовывод типов сюда не завезли

Да, это я с выводом типов для дженериковых методов спутал.

_Vasilisk_
Нельзя. Дженерик-функций не бывает

А это я с FPC спутал, там они есть :)
29 мар 21, 15:37    [22301493]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 6314
DmSer,

в любом случае если у тебя появляется AS, значит код уже сразу выглядит аналогично тому как звучит
нельзя использовать хаки везде подряд, карма портится
29 мар 21, 15:44    [22301501]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 6314
_Vasilisk_
Kazantsev Alexey
можно сократить до:
Нельзя.
1. TSmartPointer и TSmartPointer<T> - это разные типы.
2. Можно было бы писать
x := TSmartPointer<>.Create(TForm2.Create(nil));
но это вам не джава и автовывод типов сюда не завезли
Kazantsev Alexey
или вообще создание смартпоинтера завернуть в функцию,
Нельзя. Дженерик-функций не бывает
как вариант можно хелпером к TObject, мало уже кто функции пишет чистые
29 мар 21, 15:46    [22301504]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
DmSer
Member

Откуда: Пенза
Сообщений: 1347
kealon(Ruslan)
DmSer,

в любом случае если у тебя появляется AS, значит код уже сразу выглядит аналогично тому как звучит
нельзя использовать хаки везде подряд, карма портится


Мы пока на D2007 работаем. Деваться некуда :))
29 мар 21, 15:51    [22301507]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1825
_Vasilisk_
Нельзя. Дженерик-функций не бывает


Бывают)
  TStatic = class
  public
    class function Test<T: class>(const aObj: T): T; static;
  end;

Например так :)

Сообщение было отредактировано: 29 мар 21, 16:32
29 мар 21, 16:39    [22301534]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1825
А вообще в Spring 4D реализованы smart pointers на вкус и цвет..

  {$REGION 'Shared smart pointer'}

  IShared<T> = reference to function: T;

  {$REGION 'Weak smart pointer'}

  IWeakReference<T> = interface
29 мар 21, 16:44    [22301536]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 15181
X-Cite
Да все равно... Можно и Free


а если останется ссылка и ты будешь проверять и обращаться? будет AV
думаю, FreeAndNil - правильный всегда вариант
29 мар 21, 18:34    [22301627]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
alekcvp
Member

Откуда:
Сообщений: 2792
X11
X-Cite
Да все равно... Можно и Free

а если останется ссылка и ты будешь проверять и обращаться? будет AV
думаю, FreeAndNil - правильный всегда вариант

Какая ссылка, если речь идёт о деструкторе?.. Если у тебя после этого останется ссылка, к которой ты будешь обращаться, то ты ССЗБ.
29 мар 21, 19:27    [22301650]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
X11
Member

Откуда: Kharkiv, Ukraine
Сообщений: 15181
после Free остается ссылка
не зря ведь придумали FreeAndNil

o := TObject.Create;
o.Free;

if Assigned(o) then o.Width := 10;


По идее Assigned(o) вернет True

Сообщение было отредактировано: 29 мар 21, 19:40
29 мар 21, 19:46    [22301663]     Ответить | Цитировать Сообщить модератору
 Re: Автоматическое уничтожение объектов  [new]
rgreat
Member

Откуда:
Сообщений: 6653
X11
после Free остается ссылка
не зря ведь придумали FreeAndNil

o := TObject.Create;
o.Free;

if Assigned(o) then o.Width := 10;


По идее Assigned(o) вернет True

А не надо так делать.

Вообще с Assigned надо быть очень аккуратным и точно знать как работает то что туда передаешь.
Ибо если не уверен на 100% что в o может быть либо живой объект либо nil то Assigned применять вообще нельзя.

Сообщение было отредактировано: 29 мар 21, 20:02
29 мар 21, 20:06    [22301671]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить