![]() |
|
Модераторы: Poseidon, Snowy, bems, MetalFan |
![]()
|
|
| Ibragim |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Всем ночи доброй.
Такая ситуация: объект класса TMyClass сам решает при создании, есть ли подходящие условия для создания себя. Нужно, чтобы пользователь вызывал Create, а получал в ответ nil - и при этом не засорялась память и т.п. То есть хочется сделать так: constructor TMyClass.Create begin <...> if <нехочу создаваться> then self := nil; <...> end Как это правильно сделать, чтобы объект не создавался? Чтобы не выделялась память под переменные, и т.д. Заранее спасибо. |
|||
|
||||
| ДЫМ |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 224 Регистрация: 6.1.2004 Репутация: 8 Всего: 8 |
Попробуй сгенерировать "тихое исключение"
if <нехочу создаваться> then Abort; |
|||
|
||||
| <Spawn> |
|
|||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 44 Всего: 64 |
Ibragim Примерно так:
-------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
|||
|
||||
| Ibragim |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Понятно... Будем пробовать. А так чтобы
MyObject : TMyClass; begin MyObject := TMyClass.Create; if MyObjec = nil then .... никак сделать нельзя? Моим классом будут пользоваться другие, и невозможность создать объект класса у меня не исключение, а довольно стандартная ситуация. Предполагается, что пользователь моего класса обязательно проверит - создалось что-то или нет. И если просто возвращать nil вместо указателя на класс было бы самое оно. Но если нет - что ж, будем делать как советовали. В любом случае большое спасибо. |
|||
|
||||
| p0s0l |
|
||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Можно сделать так:
Пример:
Это сообщение отредактировал(а) p0s0l - 4.10.2004, 12:07 -------------------- С уважением, г-н Посол. |
||||||
|
|||||||
| Ibragim |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Спасибо. А что значит "предложенный способ не совсем правильный"? Какой способ? Твой? Тогда как совсем правильно?
|
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Ну да... То, что я предложил - не совсем правильно, потому что делается xor esi, esi... Это типа обмана компилятора.
Щас в голову пришёл более правильный способ (вернее, в нём уже ничего неправильного не будет):
-------------------- С уважением, г-н Посол. |
|||
|
||||
| <Spawn> |
|
|||
![]() Око кары:) ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2776 Регистрация: 29.1.2003 Где: Екатеринбург Репутация: 44 Всего: 64 |
Кстати, интересный вопрос, вот такой код показывает что указатель при моем примере не инициализируется:
Но вот вопрос, а все ли данные от TObject корректно высвобождаются? Ни где про это не встречал описание, а всегда вызывал исключение в случае надобности, но правильно ли это p0s0l Ну тут даже и class function не нужно делать -------------------- "Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков. |
|||
|
||||
| p0s0l |
|
||||||||||||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Если я в программе использую TBitmap, то в .exe (и в памяти) тоже будет код конструктора TBitmap.Create. Или я неправильно тебя понял... Объясни подробнее...
c := TMyClass.Create а не c := CreateMyClass; Тем более, что если применить приведённый подход, то никакой разницы ни для программиста, ни для юзера не будет. Ты разве почуствуешь разницу, Create - это конструктор или функция ? c := TMyClass.Create(..), и даже не задумаюсь, конструктор это или функция... И при таком подходе возможно то, чего хочет Ibragim: MyObject := TMyClass.Create; if MyObject = nil then ....
Сравни 2 варианта:
и второй вариант:
Чтобы окончательно развеять твои сомнения, можно заменить все эти манипуляции с AbortConstruction и Exit теми же исключениями, и ловить эти исключения в класс-функции Create... Тогда это будет выглядеть так:
-------------------- С уважением, г-н Посол. |
||||||||||||||||
|
|||||||||||||||||
| Ibragim |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 177 Регистрация: 28.9.2004 Где: Киев Репутация: нет Всего: нет |
Спасибо за интересные рассказы. В моем случае тормозов не будет - объемы выделения памяти не те. Хотя в контексте интересно.
Тогда Гуру - хотите еще вопрос? Совсем сложный? Я даже и не спрашивал - но вдруг и так можно... Значит есть большое дерево классов, каждый класс, понятное дело, знает о своем родителе но ничего не ведает о потомке. Нужно обойти это дерево классов и создать наиболее подходящий объект по таким критериям: 1. единственный параметр - строка, получаемая в процессе работы (положим, из физического порта) 2. каждый класс может оценить по этой строке возможность создания экземпляра себя, и только саму возможность: могу создаться/не могу создаться 3. наиболее подходящий объект - это объект на наиболее удаленной от корня дерева ветке. 4. два объекта считаем одинаково подходящими, если они на одинаковом удалении от корня дерева - тогда одинаково хорошо любое решение. Для пользователя все должно выглядеть так: MyObject: TBaseClass; MyObject := TBaseClass.Create; а в MyObject - указатель на наиболее подходящий объект (ну или nil). прошу заметить из приведенного примера, что менеджера классов создавать нельзя - классы сами должны между собой "договориться" - какой объект создавать. Это сообщение отредактировал(а) Ibragim - 4.10.2004, 19:23 |
|||
|
||||
| p0s0l |
|
||||||||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 58 Всего: 112 |
Проще было бы сделать так:
Если же идти таким способом, как ты сказал, то всё равно надо делать что-то для того, чтобы знать, какие возможные классы можно создать... Имхо, легче всего это сделать, если объявить массив, в котором будут указаны всевозможные наследники. Пример. Есть такое дерево:
1 и 2 критерии будут проверяться функцией CheckString. Эта функция переписывается в каждом новом наследнике от TBaseClass и от его потомков. 3 и 4 критерии будут осуществляться в TBaseClass. Т.к. constructor TBaseClass сам по себе создаёт экземпляр TBaseClass (а нам надо создать наследника от него), то вместо конструктора надо использовать функцию/класс-функцию. И опять же, т.к. для 2 критерия надо проверять для каждого класса истинность условия, то придётся эту функцию проверки делать класс-функцией. Обычным методом сделать нельзя, т.к. самого экземпляра класса не существует еще (буди что временно создавать, но это криво).
Теперь если сделать так:
Есть способ без всяких массивов и других специальных прибамбасов. Только он опять же будет не совсем правильный... И к тому же, в любом случае, кроме объявления и реализации класса, надо делать ссылку на него (например, в глобальной переменной), иначе этот класс не будет участвовать в компиляции... -------------------- С уважением, г-н Посол. |
||||||||
|
|||||||||
![]()
|
| Правила форума "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. |