Название: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 13:24 Доброго времени всем !
Тут столкнулся с такой задачкой: 1. например при создании какого нибудь класса (оператором new) необходимо как-то его идентифицировать, т.е отличать его от других таких же классов... 2. количество создаваемых таким образом классов ограничено допустим числом в 2000 штук 3. каждый такой класс "внутри" имеет некую ЦЕЛУЮ (int) переменную id ... идея в том, чтобы из множества созданных однотипных классов отыскать класс с нужным идентификатором - и потом с ним работать! так вот: 1. каким образом при создании класса генерировать эту переменную ID так, чтобы однозначно она определяла этот класс (т.е не повторялась и т.п.) ? 2. может есть какие-то стандартные методы в QT? Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 13:27 сделайте статическую переменную в классе и в конструкторе инкрементируйте ее.
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 13:41 а если я хочу и удалять объекты к примеру... то не напасешься разрядностью этого счетчика
например 1. создал 2000 объектов, Cnt=1-2000, 2. удалил из них 1000 3. создал еще 1000 -> Cnt=2001-3000 !!! (т.е не используются те значения ID которые были в удаленных мною объектах) т.е получается нифига не экономия! ЗЫ: я раньше так делал... но это не то Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: pastor от Январь 20, 2009, 13:45 1. как уже предложил спирит, использовать статический член класс:
Код
При этом, objectsCount будет содержать общее кол-во созданных объектов. 2. А если просто использовать QMap? Например: QMap<int, YourClass *> list; при этом, ключ будет id вашего класса. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 13:47 а если я хочу и удалять объекты к примеру... то не напасешься разрядностью этого счетчика что значит "неэкономия"? после удаления объектов уже ж не будет, а какая разница с какого числа будет айди начинаться?например 1. создал 2000 объектов, Cnt=1-2000, 2. удалил из них 1000 3. создал еще 1000 -> Cnt=2001-3000 !!! (т.е не используются те значения ID которые были в удаленных мною объектах) т.е получается нифига не экономия! ЗЫ: я раньше так делал... но это не то еще как вриант советую вам почитать про шаровые классы и как они организованы. в принципе идее та же. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: Rcus от Январь 20, 2009, 13:50 если у вас объекты некопируемы, то что мешает в качестве уникального идентификатора объекта использовать указатель на него?(они совершенно точно уникальны в каждый момент времени и используются заново :)) Хотя конечно если нужно хранение идентификаторов, то такой способ не подходит
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 13:55 Цитировать Хотя конечно если нужно хранение идентификаторов, то такой способ не подходит да! именно эти ID-ы должны храниться в БД...Цитировать что значит "неэкономия"? после удаления объектов уже ж не будет, а какая разница с какого числа будет айди начинаться? а если объектов не 2000 а 200000! и например в процессе "конфигурирования" приложения - придется удалять/добавлять новые объекты... при этом счетчик будет делать ++ ... но счетчик - не резиновый! и например после определенного кол-ва добавлений/удалений объектов - счетчик просто переполнится ! так что это решение - на крайняк , если ничего лучше не придумается :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 13:58 декрементируйте в деструкторе ;)
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 14:05 Цитировать декрементируйте в деструкторе Подмигивающий не покатит! (увы) :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: Rcus от Январь 20, 2009, 14:07 Интересно все же, какой смысл хранить эти идентификаторы во внешнем хранилище, если время жизни объекта настолько мало, что вы боитесь переполнения целочисленного счетчика?
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 14:09 Интересно все же, какой смысл хранить эти идентификаторы во внешнем хранилище, если время жизни объекта настолько мало, что вы боитесь переполнения целочисленного счетчика? +1Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 14:27 Цитировать Интересно все же, какой смысл хранить эти идентификаторы во внешнем хранилище, если время жизни объекта настолько мало, что вы боитесь переполнения целочисленного счетчика? +1 :) оно не мало! оно велико! я наверное плохо обрисовал ситуевину: 1. при конфигурировании приложения (создании/удалении) объектов - информация о них сохраняется в БД (сохраняется и их ID) 2. ID необходим, чтобы к этим объектам можно было "привязать" другие объекты! 3. у других объектов - в БД храниться инфа : их ID + ID того объекта к которому их нужно привязать!. т.е при старте приложения ( рабочий режим) происходить должно следующее: 1. сканируется БД "родительских объектов" 2. по информации, записанной в ней - создаются эти объекты в оперативной памяти (+ им присваиваются уникальные ID-ы которые были сохранены в их БД) 3. сканируется БД "дочерних" объектов. 4. по информации, записанной в этой БД (БД хранит не только ID дочернего но и ID родительского объекта) - создаются эти дочерние объекты со своими параметрами + создаются они в тех родительских объектах в которых ID-ы совпадают!!! т.е ID-ы должны быть уникальными, чтобы все было нормуль! ЗЫ: просто я смотрю наверное на все это не с позиции "чистого" программиста куллхацкера - а с позиции алгоритмиста АСУТП :) поэтому и по-другому наверное выражаюсь Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: pastor от Январь 20, 2009, 14:32 2 kuzulis: возми не int, a unsigned int (что более логично) Это 4294967295 объектов. Мало? Возмите unsigned long long если позволяет платформа, это 18446744073709551615 объектов. Но думаю unsigned int для вашей задачи будет достаточно.
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 14:32 а если айди при создании устанавливать в "0", а после записи в БД выгребать уникальный айди , который сгенерила база?
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 14:34 2pastor ?
;D спс канешн.. я об этом думал.. но решил спросить тута.. может что-то в QT такое есть само по себе? :) ну... что-то вроде как в винде дескрипрор на что-то там.. его же само ядро ОС генерит.. и он уникальный! (наверное) :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: pastor от Январь 20, 2009, 14:38 ну... что-то вроде как в винде дескрипрор на что-то там.. его же само ядро ОС генерит.. и он уникальный! (наверное) :) Дискрипотор это тоже какой-то интергральный тип, который имеет свой придел :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 14:40 Цитировать а если айди при создании устанавливать в "0", а после записи в БД выгребать уникальный айди , который сгенерила база? а как база сама сгенерит? Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 14:46 primary key -- может генирится самой базой, как это делается зависит от конкретного сервера:
в MYSQL -- при создании таблы добавляется AUTO_INCREMENT, в Oracle -- клепается последовательность (sequence), в PostgreSql -- при создании таблы добавляется SERIAL, в SqLite -- вроде так же как и в MySql (точно не помню). получать этот айди можно через QVariant QSqlQuery::lastInsertId () const, но для Oralce & PostgreSql не возвращает. для них я получал айди самописным методом. но имхо, самый быстрый вариант -- это тот , о котором говорил я и пастор. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 14:58 ОК :)
спс... буду делать через счетчик. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: lit-uriy от Январь 20, 2009, 15:15 вообще задачка по ID объекта из области "именованного/нумерованого одиночки", я думаю такой вариант и надо использовать.
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: Winstrol от Январь 20, 2009, 15:32 Нужно будет завести словарь std::map<IdInDBType,KewlClass*> и в рантайме конвертировать ID в указатель на объект.
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 20, 2009, 15:51 Цитировать вообще задачка по ID объекта из области "именованного/нумерованого одиночки", я думаю такой вариант и надо использовать. я не понял ничего :) Цитировать Нужно будет завести словарь std::map<IdInDBType,KewlClass*> и в рантайме конвертировать ID в указатель на объект. а по подробнее идею растолкуйте :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: Winstrol от Январь 20, 2009, 15:54 primary key -- может генирится самой базой, как это делается зависит от конкретного сервера: Давно с БД не имел дела, но на край на SQL можно эмулировать авто инкремент как-то так select max(ID)+1 from ...Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: spirit от Январь 20, 2009, 15:56 primary key -- может генирится самой базой, как это делается зависит от конкретного сервера: Давно с БД не имел дела, но на край на SQL можно эмулировать авто инкремент как-то так select max(ID)+1 from ...Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: panAlexey от Январь 20, 2009, 16:47 Автоинкремент в данном случае не подходит.
Я так понимаю, что у него разные классы, а следовательно автоинкременные значения могут попросту совпасть. Если конечно у него экземпляры классов хранятся в разных таблицах. Если в одной, то - ОК. Если в разных, то сводная таблица+транзакция или составное значение: видКласса+ID объекта. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: Dendy от Январь 20, 2009, 17:52 А в каком виде вам нужен этот уникальный идентификатор? Я так понимаю - это целое неповторяющееся число из определённого диапазона с возможностью утилизировать удалённые идентификаторы во избежание переполнения счётчика. Верно?
Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: lit-uriy от Январь 20, 2009, 17:58 Цитировать вообще задачка по ID объекта из области "именованного/нумерованого одиночки", я думаю такой вариант и надо использовать. я не понял ничего :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 21, 2009, 08:37 Цитировать А в каком виде вам нужен этот уникальный идентификатор? в любом, который можно сохранить либо в конф. файле или БД ... + чтобы меньше памяти занимал + чтобы скорость работы была высокая Цитировать Я так понимаю - это целое неповторяющееся число из определённого диапазона с возможностью утилизировать удалённые идентификаторы во избежание переполнения счётчика. Верно? ага... и не только удалять, но и использовать для вновь создаваемых объектов идентификаторы ранее удаленных объектов --- я пока алгоритм такой наваял: (при создании нового объекта вручную) 1. счетчик = 0 2. создаем объект 3. инкремент счетчика (т.е ID-ы будут от 1 до ....) 4. проверяем ID-ы уже имеющихся объектов и сравниваем их значения с текущим значением счетчика.. 5. если есть совпадения ID-ов - переход к п. 3 6. присваиваем созданному объекту ID = тек. значение счетчика... (при создании объектов автоматически - т.е при чтении конфига БД) 1. проверку на повторяющиеся ID-ы не делаем, т.к подразумеваем что в БД все ID-ы уже разные и все там правильно Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kirill от Январь 21, 2009, 11:26 Алгоритм полного перебора, мягко говоря, неоптимален по времени.
А может использовать ID, создаваемый таймером ? #include <time.h> clock_t ID = clock(); Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 21, 2009, 12:40 Цитировать Алгоритм полного перебора, мягко говоря, неоптимален по времени. А может использовать ID, создаваемый таймером ? #include <time.h> clock_t ID = clock(); а этот ID разве не может повториться ? Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: pastor от Январь 21, 2009, 12:46 Алгоритм полного перебора, мягко говоря, неоптимален по времени. +1 Если вы боитесь переполнить unsigned int (а это 4294967295 объектов), то подумайте над производительностью вашего алгоритма генерирования ID. Ва нужно будет всегда пробегать по всем объектам и искать повторения. Но, ваш алгоритм можно улучшить, путем хранения ID в списке и предварительной его сортировки перед началом его работы. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: pastor от Январь 21, 2009, 12:50 а этот ID разве не может повториться ? Цитировать The clock function's era begins (with a value of 0) when the C program starts to execute. It returns times measured in 1/CLOCKS_PER_SEC (which equals 1/1000 for Microsoft C). Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kirill от Январь 21, 2009, 12:54 а этот ID разве не может повториться ? Это количество милисекунд от начала новой эры, сиречь 1 января 1970 года. Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: kuzulis от Январь 21, 2009, 13:06 Спасибо всем за помощь!
буду пробовать! :) Название: Re: Как создать объект с уникальным для него идентификатором? Отправлено: Dendy от Январь 21, 2009, 14:01 Кажется я понял что вам нужно. Для себя написал небольшой класс для этой задачи, но тем не менее он уже используется у меня в проекте в нескольких местах - уже больно полезный оказался.
http://dendy.org.ua/idgenerator.zip Единственно что вам нужно в него добавить - сериализацию/десериализацию, а также возможность выбора собственных идентификаторов, если вы их где-то сохраняете. |