четверг, 5 октября 2017 г.

Научился делать "настоящие" immutable объекты

Научился делать "настоящие" immutable объекты.

Через перекрытие NewInstance + VirtualAlloc + VirtualProtect.

Перекрываем NewInstance - там аллоцируем память через VirtualAlloc (там есть тонкости с размером страниц и стратегией выделения памяти).

Потом заполняем поля объекта в конструкторе. И "закрываем" доступ на запись через VirtualProtect + Page_ReadOnly - в AfterCreate.

Потом в FreeInstance (или destroy - тут есть тонкости) опять разрешаем доступ.

Получаем гарантировано неизменяемые объекты.

Например для паттерна flyweight.

Или например для случая:

ConstString = interface
 Function S: PChar;
End;

Ничто не мешает сделать так:

Var Cs: ConstString;

Cs := Factory.GetCs('value');
Cs.S^ := 'xxx';

Т.е "кишки" объекта будут испорчены.

А вот virtualProtect + page_readonly - решают эту проблему.

Комментариев нет:

Отправить комментарий