Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2008.08.10;
Скачать: [xml.tar.bz2];

Вниз

Как узнать количество экземпляров класса?   Найти похожие ветки 

 
@!!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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.51 MB
Время: 0.007 c
9-1172925794
PARUS
2007-03-03 15:43
2008.08.10
"Игра" - потестите


15-1213883179
Dmitry S
2008-06-19 17:46
2008.08.10
сила/ускорение/скорость


4-1194246203
Sunshine
2007-11-05 10:03
2008.08.10
Программная имитация COM порта.


2-1215676956
Артур Пирожков
2008-07-10 12:02
2008.08.10
Простой вопрос по tpopupmenu


1-1196554693
Elec3C
2007-12-02 03:18
2008.08.10
Вопрос по HotKey ям





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский