Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Delphi |
![]() ![]() |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
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] Ответить | Цитировать Сообщить модератору |
X-Cite Member Откуда: Минск Сообщений: 1825 |
Умный указатель через reference to function интереснее... там даже подсказчик кода работает и синтаксис использования не меняется, кроме объявления... |
29 мар 21, 13:59 [22301415] Ответить | Цитировать Сообщить модератору |
DmSer Member Откуда: Пенза Сообщений: 1347 |
Где посмотреть на это? |
||||
29 мар 21, 14:03 [22301420] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
function RegObj<T: class>(const AVal: T): T;
|
||||||||||||
29 мар 21, 14:07 [22301424] Ответить | Цитировать Сообщить модератору |
rgreat Member Откуда: Сообщений: 6653 |
ИМХО это не красиво и не очень удобно. Не надо связываться с интерфейсами, где это явно не требуется. В конце концов если сильно хочется - используй рекорды. Благо там теперь и конструктор с деструктором есть. |
29 мар 21, 14:15 [22301430] Ответить | Цитировать Сообщить модератору |
DmSer Member Откуда: Пенза Сообщений: 1347 |
Там объект, который хранит список зарегистрированных объектов в TList. Объект реализует интерфейс. В рекорде хранится интерфейсная ссылка на этот объект.
Можно, как вариант.
Разные ситуации бывают, конечно. |
||||||
29 мар 21, 14:20 [22301432] Ответить | Цитировать Сообщить модератору |
DmSer Member Откуда: Пенза Сообщений: 1347 |
В коде нет явной работы с интерфейсами (см. пример в начале). Всё спрятано в методы рекорда. Интерфейсная ссылка объявлена как private. |
||||
29 мар 21, 14:23 [22301438] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
DmSer Member Откуда: Пенза Сообщений: 1347 |
Использование RegObj выглядит не очень красиво. К сожалению. Тут ничего не поделаешь. Но такой код смотрится вполне прилично:
var L := h.CreateStringList();
можно так:
var L := TStringList.Create();
h.RegObj(L);
У меня в коде есть классы, которые я чаще всего использую (назовём их "типовые классы"). Для них сделал функции создания объекта (CreateStringList, CreateList и т.п.). Иногда добавляю новые функции по мере необходимости. Но это свой фирменный велосипед :) |
29 мар 21, 14:31 [22301445] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
X-Cite Member Откуда: Минск Сообщений: 1825 |
alekcvp, Да все равно... Можно и Free Ну это уже проблемы компилятора, если он не сможет заинлайнить))) За сомнительное удобство, не из коробки, надо платить... |
29 мар 21, 14:41 [22301456] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 5101 |
Это же интерфейс, откуда там инлайну взяться. Однако, прикольное колдунство :) Сообщение было отредактировано: 29 мар 21, 14:38 |
||||
29 мар 21, 14:45 [22301459] Ответить | Цитировать Сообщить модератору |
DmSer Member Откуда: Пенза Сообщений: 1347 |
Не заметил особого преимущества по сравнению с var x: TForm2; h: TSmartHolder; begin x := h.RegObj(TForm2.Create(nil)) as TForm2; А пытаться понять как работает ISmartPointer - ещё сложнее, чем разобраться с фильмом Довод :) |
||
29 мар 21, 15:07 [22301469] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 5101 |
Если правильно помню, эту запись:
x := TSmartPointer<TForm2>.Create(TForm2.Create(nil));
можно сократить до:
x := TSmartPointer.Create(TForm2.Create(nil));
или вообще создание смартпоинтера завернуть в функцию, например:
x := Auto(TForm2.Create(nil));
|
||||
29 мар 21, 15:17 [22301473] Ответить | Цитировать Сообщить модератору |
_Vasilisk_ Member Откуда: Украина, Харьков Сообщений: 12789 |
1. TSmartPointer и TSmartPointer<T> - это разные типы. 2. Можно было бы писать
x := TSmartPointer<>.Create(TForm2.Create(nil));
но это вам не джава и автовывод типов сюда не завезли
|
||||||||
29 мар 21, 15:28 [22301484] Ответить | Цитировать Сообщить модератору |
Kazantsev Alexey Member Откуда: Сообщений: 5101 |
Верно, только не специализированных дженериков не бывает.
Да, это я с выводом типов для дженериковых методов спутал.
А это я с FPC спутал, там они есть :) |
||||||||||||
29 мар 21, 15:37 [22301493] Ответить | Цитировать Сообщить модератору |
kealon(Ruslan) Member Откуда: Нижневартовск Сообщений: 6314 |
DmSer, в любом случае если у тебя появляется AS, значит код уже сразу выглядит аналогично тому как звучит нельзя использовать хаки везде подряд, карма портится |
29 мар 21, 15:44 [22301501] Ответить | Цитировать Сообщить модератору |
kealon(Ruslan) Member Откуда: Нижневартовск Сообщений: 6314 |
|
||||||||||||
29 мар 21, 15:46 [22301504] Ответить | Цитировать Сообщить модератору |
DmSer Member Откуда: Пенза Сообщений: 1347 |
Мы пока на D2007 работаем. Деваться некуда :)) |
||||
29 мар 21, 15:51 [22301507] Ответить | Цитировать Сообщить модератору |
X-Cite Member Откуда: Минск Сообщений: 1825 |
Бывают) TStatic = class public class function Test<T: class>(const aObj: T): T; static; end; Например так :) Сообщение было отредактировано: 29 мар 21, 16:32 |
||||
29 мар 21, 16:39 [22301534] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
X11 Member Откуда: Kharkiv, Ukraine Сообщений: 15181 |
а если останется ссылка и ты будешь проверять и обращаться? будет AV думаю, FreeAndNil - правильный всегда вариант |
||||
29 мар 21, 18:34 [22301627] Ответить | Цитировать Сообщить модератору |
alekcvp Member Откуда: Сообщений: 2792 |
Какая ссылка, если речь идёт о деструкторе?.. Если у тебя после этого останется ссылка, к которой ты будешь обращаться, то ты ССЗБ. |
||||||||
29 мар 21, 19:27 [22301650] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
rgreat Member Откуда: Сообщений: 6653 |
А не надо так делать. Вообще с Assigned надо быть очень аккуратным и точно знать как работает то что туда передаешь. Ибо если не уверен на 100% что в o может быть либо живой объект либо nil то Assigned применять вообще нельзя. Сообщение было отредактировано: 29 мар 21, 20:02 |
||||
29 мар 21, 20:06 [22301671] Ответить | Цитировать Сообщить модератору |
Топик располагается на нескольких страницах: [1] 2 вперед Ctrl→ все |
Все форумы / Delphi | ![]() |