Текущий архив: 2008.08.10;
Скачать: CL | DM;
Вниз
Как узнать количество экземпляров класса? Найти похожие ветки
← →
@!!ex © (2008-07-09 15:26) [0]Суть задачи:
Есть класс TMyClass.
У него есть ID.
В конструкторе надо ID менять. так, чтобы первому созданному экземпляру ставилось 1, второму - 2, и так далее.
Причем светчик должен быть уникальным для класса. Тоесть если мы делаем наследника, то наследник должен иметь свой счетчик. Как это лучше всего сделать?
← →
Palladin © (2008-07-09 15:31) [1]глобальная карта соответствий
класс - счетчик
← →
Поросенок Винни-Пух © (2008-07-09 15:36) [2]приватный TList в модуле класса и занесение в него экземпляров в конструкторе с проверкой на класснейм чтобы наследники не вносились.
счетчиком будет индекс добавленного экземпляра.
← →
Поросенок Винни-Пух © (2008-07-09 15:43) [3]либо просто переменная счетчик в модуле класса
← →
Palladin © (2008-07-09 15:48) [4]
> Поросенок Винни-Пух © (09.07.08 15:43) [3]
в случае наследования - некатит
← →
Поросенок Винни-Пух © (2008-07-09 15:55) [5]да все катит. надо только пару конструктор с булевым параметром и диспетчер конструктора
← →
Dennis I. Komarov © (2008-07-09 15:56) [6]> [0] @!!ex © (09.07.08 15:26)
А если сделали 1, 2, 3, 4, 5, потом убили 3, следующий создавать какой?
← →
Поросенок Винни-Пух © (2008-07-09 15:58) [7]constructor CreateIt(AOwner : TComponent; BIncrement : boolean);
begin
inherited Create(AOwner);
if BIncrement then Inc(fCounterA);
end;
constructor DescendantCreateIt(AOwner : TComponent; BIncrement : boolean);
begin
inherited CreateIt(AOwner, False);
if BIncrement then Inc(fCounterB);
end;
← →
Palladin © (2008-07-09 16:06) [8]
> Поросенок Винни-Пух © (09.07.08 15:58) [7]
а зачем нам при создании наследника еще и родителя счетик накручивать?
← →
Palladin © (2008-07-09 16:08) [9]
> Поросенок Винни-Пух © (09.07.08 15:58) [7]
звиняюсь... непросек... но решение дубовое
реально хватит в родителе
Inc(CountersMap[Class]);
и можешь в наследниках забыть о каких либо счетчика
← →
Kolan © (2008-07-09 16:26) [10]Может использовать классовые методы?
Вообще, конечно, нужен ответственный за инстанцирование, то есть фабрика.
← →
Palladin © (2008-07-09 16:28) [11]обоснуй
← →
@!!ex © (2008-07-09 16:28) [12]> [6] Dennis I. Komarov © (09.07.08 15:56)
6. в данном случае это лишь для того, чтобы соблюсти уникальность имен.
Типа как в дельфи, когда на форму кидаешь кнопку, у нее автоматически имя имеет порядковый номер. для уникальности.
Задача стоит в точности такая же. Создание визуального редактора.
Сделал около каждого наследника в модуле счетчик, в итоге при создании наследника приходится позаботиться об имени, но это не такая уж и проблема.
← →
Kolan © (2008-07-09 16:37) [13]> обоснуй
Кто-то должен вести подсчёт. Логично, что удобнее всего это делать при создании и удалении. Фабрики и нужны для того, что бы создавать объекты.
Можно, напрмер, сделать так:Obj := Factory.CreateObject;
try
Obj.ThisIsMyUnitedStatesOfWhatEver;
finally
Factory.Utilize(Obj);
end;
То есть получать объекты с фабрики и сдавать их обратно в утиль :). А фабрика пусть считает.
> Типа как в дельфи, когда на форму кидаешь кнопку, у нее
> автоматически имя имеет порядковый номер. для уникальности.
> Задача стоит в точности такая же. Создание визуального редактора.
Дык и пользуй этот дэлфаевский готовый метод, GetUniqueName называется, или как-то так?
← →
Palladin © (2008-07-09 16:38) [14]
> Кто-то должен вести подсчёт. Логично, что удобнее всего
> это делать при создании и удалении.
с головой хватит конструтора и деструктора
← →
Kolan © (2008-07-09 16:41) [15]> Сделал около каждого наследника в модуле счетчик, в итоге
> при создании наследника приходится позаботиться об имени,
> но это не такая уж и проблема.
Имхо, плохое решение. При добавлении наследников придётся добавлять и счётчик. Кроме того, придется добавлять видимость модуля везде где нужны счётчики.
← →
Поросенок Винни-Пух © (2008-07-09 16:43) [16]Кроме того, придется добавлять видимость модуля везде где нужны счётчики.
А можно не добавлять в юзез модуль наследника там где нужны наследники?
← →
Kolan © (2008-07-09 16:46) [17]> с головой хватит конструтора и деструктора
Влучае иерархии с несколькими корневыми классами, то есть, когда несколько иерархий, придётся дублировать. А в фабрике всеравно останется один вызов.
Хотя, я не настаиваю, можно и так и эток. Можно вообще имена по счётчики инкрементировать или каждый раз GUID генерить, и вообще без подсчёта обойтись.
← →
Kolan © (2008-07-09 16:54) [18]> А можно не добавлять в юзез модуль наследника там где нужны
> наследники?
Можно. При реализации Паладина вообще ничего ненадо добавлять:Пример упрощен.
1. Модуль А, тут описаны классы.
Общий предок такой:TCustom = class
function GetInstanciesCount: Integer;
end;
И наследник, допустим такой:TDescendant = class(TCustom)
end;
2. Допустим имеем фасад/синглетон, модуль B:uses A
TFacade = class
function GetObject: TDescendant
end;
3. И еще модуль С, использующий фасад:uses B
...
begin
ShowMessage(IntToStr(TFacade.GetInstance.GetObject.GetInstanciesCount));
end;
← →
han_malign © (2008-07-09 17:52) [19]
> Причем светчик должен быть уникальным для класса.
- зарезервировать место в VMT виртуальным методом-заглушкой и использовать для хранения счетчика/маски... только, если наследник не перекроет ни одного виртуального метода родителя - счетчик/маска будет родительским(новый VMT не будет создан)...
← →
@!!ex © (2008-07-09 17:58) [20]> - зарезервировать место в VMT виртуальным методом-заглушкой
> и использовать для хранения счетчика/маски...
А как это сделать??
> только, если наследник не перекроет ни одного виртуального
> метода родителя - счетчик/маска будет родительским(новый
> VMT не будет создан)...
Это невозможно. Наследник обязательно перекрывает кучу методов, иначе он нафиг не нужен.
← →
han_malign © (2008-07-09 18:16) [21]где-то примерно так
_TfakeClassCount = class
protected
procedure _falkeCOunter; virtual;
end;
TfakeClassCount = class(_TfakeClassCount)
private
procedure _falkeCOunter; override;//hide method
protected
function _GetCounter: Pointer;
end;
function TfakeClassCount._GetCounter: Pointer;
asm
mov EAX, [EAX]//get VMT address
lea [EAX+ VMTOFFSET _TfakeClassCount._falkeCOunter]//get VMT entry address
end;
............
... PDWORD(_GetCounter)^ ...
← →
Поросенок Винни-Пух © (2008-07-09 18:24) [22]А кто-то здесь упоминал дубовые решения
← →
oxffff © (2008-07-09 21:51) [23]
> @!!ex © (09.07.08 15:26)
Перекрыть Newinstance и изучить исходники реализации dynamic методов в Delphi для .NET. И сделать аналогично.
← →
Тын-Дын © (2008-07-10 01:44) [24]
> @!!ex © (09.07.08 16:28) [12]
>
> > [6] Dennis I. Komarov © (09.07.08 15:56)
>
> 6. в данном случае это лишь для того, чтобы соблюсти уникальность
> имен.
Тогда вообще в чем проблема?
type
TMyClass=class
private
FId: Integer;
public
constructor Create;
end;
var
GlobalId: Integer=0;
implementation
{ TMyClass }
constructor TMyClass.Create;
begin
FId := InterLockedIncrement(GlobalId);
end;
← →
Palladin © (2008-07-10 13:00) [25]у TObject есть замечательный метод ClassType:TClass, результатом которого является класс который инстанцируется, если стоит задача считать экземпляры, то есть смысл создать общего родителя классов со счетчиками и считать до потери пульса, бо self.classtype вернет именно тот класс который инстанцируется, далее осталось лишь реализовать класс-карту, объект которого и будет возвращать тот самый счетчик для определенного значения ClassType которое есть уникально для всего приложения
Страницы: 1 вся ветка
Текущий архив: 2008.08.10;
Скачать: CL | DM;
Память: 0.51 MB
Время: 0.006 c