Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Или Java, в которой при сравнении строк можно получить NullPointerException, если не использовать equals из стороннего пакета Apache Commons.Неубедительно.
Автоматическое управление памятью. Лестница из try… finally — это не серьёзно
obj1 := nil;
obj2 := nil;
try
obj1 := TClass1.Create;
obj2 := TClass2.Create;
....
finally
obj1.Free;
obj2.Free;
end;решение масштабируется на любое количество объектов.Copy-on-write и счётчики ссылокСчетчики ссылок встроены в
TInterfacedObject. готовое Copy-on-write реализовано только в string, остальное да, ручками.Другое особое поведение при копированииНепонятно каким образом объектная модель Delphi мешает реализовать любое копирование, как вам нужно.
Неинициализированная переменная должна вести себя как пустая строка или 0, соответственноЭто почему еще? Даже в антагонистическом С++ это не так.
Методы не могут изменить содержимое переменной–указателя, у которого они были вызваныЗачем такие извращения?
Нет контроля за тем, что происходит при копировании объекта.Встроенного копирования объектов в Delphi нет, соответственно нет и контроля. Копируйте и контролируйте сами.
Непонятно каким образом объектная модель Delphi мешает реализовать любое копирование, как вам нужно
Неинициализированная переменная должна вести себя как пустая строка или 0, соответственно
Это почему еще? Даже в антагонистическом С++ это не так
Методы не могут изменить содержимое переменной–указателя, у которого они были вызваны
Зачем такие извращения?
Нет контроля за тем, что происходит при копировании объекта.
Встроенного копирования объектов в Delphi нет, соответственно нет и контроля. Копируйте и контролируйте сами.
unit kaGarbageCollector;
interface
{$REGION 'interface uses'}
uses
// Стандартные модули:
Generics.Collections;
{$ENDREGION}
type
///<summary> Класс позволяющий упростить освобождение памяти.</summary>
TkaGarbageCollector = class
public
const
DEFAULT_TAG = 'DEFAULT_TAG';
private
items: TDictionary<TObject, string>;
public
constructor Create();
destructor Destroy; override;
///<summary> Добавить элемент в список и вернуть свежедобавленный элемент.</summary>
function add<T:class>(item: T): T; overload;
///<summary> Добавить помеченый элемент в список и вернуть свежедобавленный элемент.</summary>
function add<T:class>(const tag: string; item: T): T; overload;
/// <summary> Произвести сборку мусора с указанной меткой. </summary>
procedure gc(const tag: string);
end;
implementation
{$REGION 'TGarbageList'}
constructor TkaGarbageCollector.Create();
begin
items := TObjectDictionary<TObject, string>.Create([doOwnsKeys]);
end;
destructor TkaGarbageCollector.Destroy;
begin
items.free();
inherited Destroy;
end;
function TkaGarbageCollector.add<T>(item: T): T;
begin
result := add(DEFAULT_TAG, item);
end;
function TkaGarbageCollector.add<T>(const tag: string; item: T): T;
begin
items.add(item, tag);
result := item;
end;
procedure TkaGarbageCollector.gc(const tag: string);
var key: TObject;
item: TPair<TObject, string>;
gcList: TList<TObject>;
begin
gcList := TList<TObject>.Create();
try
for item in items do
begin
if (item.Value = tag) then
gcList.add(item.Key);
end;
for key in gcList do
items.remove(key);
finally
gcList.free();
end;
end;
{$ENDREGION}
gc := TkaGarbageCollector.Create();
try
log := gc.add(TLogStrings.Create());
warnings := gc.add(TLogStrings.Create());
partialTrips := gc.add(TLogStrings.Create());
.... code ....
finally
gc.free();
end;
Расставляем точки над i в Delphi RAII