![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Beltar |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
Так где-то или в исходниках? Я вижу, что он показывает код TBase и пишет, что "так реализовал".
Т. е. мы немедленно знаем, что у нас в переменной. В этом случае вызов ф-ии обр. вызова наименее трудозатратный способ. Если бы имелся набор переменных TBase и в каждой неизвестный наследник, тогда конечно наследование. Помоему придется в базовом классе объявлять Find(Pointer); можно пусть даже под др. именами реализовать поиск для простейших типов и строк. Имхо это разумный компромисс. Из разряда той же overload. Кстати, а так ли нужно писать класс, когда можно понаделать миллион перегруженных ф-ий? Какой-то нездоровый подход попахивающий обшарпаным Ц. Это сообщение отредактировал(а) Beltar - 5.6.2008, 11:18 -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||
|
|||||
| Koster |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
Перед вызовом функции a.find(5.7) для компилятора еще неизвестно какой именно тип параметра передается. В этом то и проблема, потому то и был использован тип variant. А потом в методе find, который является статическим, с помощью абстрактной функции ItemToPointer динамически создается переменная в памяти нужного типа (потомок то знает что там должно быть), записывается туда входной параметр и возвращает в метод find указатель. А find уже сам потом ищет среди таких же нетипизированных указателей нужный элемент. Для сравнения двух указателей используется, опять же абстрактный, метод cmp, который проверяет равны ли значения хранящиеся в этих указателях, и возвращает результат в типе integer.
Миллион перегруженных функций, ИМХО, это некрасиво. Я пока учусь, но приведу пример почему, ИМХО, это некрасиво: Например, программу пишут несколько человек, один человек делает этот класс и паралельно этот же класс (пока несуществующий, но уже известен его интерфейс) используется другим человеком. Предположим что второму человеку пришлось добавить новый тип для данного класса. Тут есть два варианта: 1. Он берет, и переделывает у себя базовый класс, получается две версии класса. Лично мне кажется это не правильным, да к тому же невозможно если этот класс еще недописан. 2. Он говорит первому программисту чтобы тот добавил новый перегруженный метод. Но в таком случае, если нужно что то подправить, нужно опять же идти к первому программисту и портить ему нервы. А потом первому программисту пришла в голову невероятно умная мысль, он вспомнил что сортировка "пузырьком" не самая эффективная и начал делать квик сорт. А у него есть миллион перегруженных методов, в которых заново сделана сортировка, и везде надо поменять ее на новую. Может если первому программисту платят за время работы а не результат, то он даже рад будет. А если нет? Если же писать через классы, тогда для того чтобы добавить второму программисту новый тип, достаточно написать новый класс и реализовать в нем нужные виртуальные методы. Ему даже не нужен тот базовый класс для этого, достаточно заглушки с ограниченым функционалом. Если я не прав в организации работы программистов в группе, подправьте. |
||||
|
|||||
| Felan |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 2.8.2007 Где: Самара Репутация: 2 Всего: 7 |
Прав, прав... и я тебе уже объяснил, как надо поступать в таких случаях. А ты все пытаешься "обработать напильником" то, что не предназначено для твоей идеи. -------------------- // Любая сложная система - это темный лес. Каждый в этом лесу протаптывает свои тропинки, по ним и бегает. Лишь изредка, сходя с них, мы находим много интересного, а порою и страшного. |
|||
|
||||
| Beltar |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
Проблема у тебя в том, что нельзя объявить перекрываемый метод с другим набором параметров. Проще всего сделать его с пойнтером. Если у тебя ищутся сложные структуры данных, то это единственный вариант. С элементарными типами это конечно неудобно и ты не сможешь вызвать a.find(5.7), но элементарных типов-то кот наплакал. LongInt, Cardinal, Extended, String, ну можно и ShortString вспомнить. 3-4 перегруженных ф-ии для них, как тебе советуют, это не проблема. И что-то я не совсем понимаю, кому может понадобиться искать отдельные числа. А строки можно хранить в наследнике TStrings.
У меня еще такой вопрос: А где сами данные-то лежат? Ну допустим все свалены в TList т. е. в простом массиве указателей. Как их различать-то? Так приходим или к контейнеру для строго определенного типа или создаем еще набор классов для хранения данных. Что вообще делает твоя софтина? Это сообщение отредактировал(а) Beltar - 6.6.2008, 11:23 -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
|||
|
||||
| pseud |
|
||||||
![]() Экспёрт Тыдыщ ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1175 Регистрация: 18.5.2007 Где: Минск, Беларусь Репутация: 10 Всего: 40 |
Koster,
ты, я думаю, уже успел поработать с такими чудными компонентами дельфи как компоненты для работы с БД. имеем конструкцию:
смотрим ее реализацию:
ай ай ай, как же так. а так. это дело реализовано в TIntegerField:
А зачем они так сделали? ООП блин. все объявили в базовом TField. А реализовали в соответствующих потомках. Думаю и тебе не стоит чураться такой практики. -------------------- Испытание чужого терпения можно считать успешным, если оно лопнуло... |
||||||
|
|||||||
| Koster |
|
||||||||||||||||
|
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 2.6.2008 Репутация: нет Всего: нет |
Зря думаешь
У меня именно так все и реализовано. Для полной ясности приведу полный интерфейс своих классов, если кому то не лень будет разбираться. Это задание было у меня на курсовой по ООП. Я ее сдал с вариантами, никаких претензий небыло. Но я хочу, чисто для себя, понять как это можна реализовать универсальнее. Вот базовый класс:
А вот пример интерфейса потомка:
Это должно было быть что то на подобие шаблонов в плюсах, естественно гораздо урезаннее по функционалу (пока) и медленнее (так как обрабатывается не компилятором). Но есть и преимущества: можна переинициализовывать одну переменную для разных типов, чего в плюсах делать, как я помню, нельзя. Опишу ту часть которая интересует больше всего: это метод find. Он в базовом классе реализован вот так:
Тут видно что все хранится в TList, т.е. в безтиповых указателях. Метод ConstToPointer - абстрактный метод задача которого получить вариант, и перевести его в такой же безтиповый указатель как и остальные элементы TList. Он состоит из таких строк:
Можно было бы сделать find виртуальным и в каждом потомке его дополнять. Но мне показалось так удобнее. Еще один абстрактный метод, который играет очень важную роль - это cmp. Он на вход получает 2 указателя, а потом сравнивает их содержимое. Вот его реализация для TIntArray:
Тут все просто. Остальные методы класса TBaseArray мало относятся к методу find. Насчет перегрузки функций, я думаю что так и буду делать. Тогда еще такой маленький вопрос. А можна ли перегружать свойства?
Это сообщение отредактировал(а) Alexeis - 7.6.2008, 11:09 |
||||||||||||||||
|
|||||||||||||||||
| Beltar |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 627 Регистрация: 11.1.2006 Репутация: 3 Всего: 7 |
А зачем тогда ООП, если все подряд в наследнике переписывать?? В protected надо было объявить. И что метод Find ищет-таки? Перебирает указатели, считая, что они определеного типа. Ну допустим у тебя запихан туда Integer, а ты ищешь Double. Внимание вопрос, а кому принадлежат еще 4 байта идущие после целого и что произойдет когда программа попытается их прочитать? Вот что-то мне подсказывает, что так можно и AV схлопотать.
Зачем использовать on, Если ты все равно не проверяешь тип исключения? -------------------- Опытный программист на C++ легко решает любые не существующие в Паскале проблемы. Пищущий на C++ мужик. Даже если это мужик сидит в написанном на Delphi и жрущем паскалевскую библиотеку билдере. |
||||
|
|||||
![]()
|
| Правила форума "Delphi: Общие вопросы" | |
|
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |