![]() |
|
Модераторы: Snowy, MetalFan, bems, Poseidon |
![]()
|
|
| boobie |
|
||||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Всем доброго времени суток!
Недавно начал знакомство с Delphi, если быть точнее, то с Object Pascal. Интересует такой момент: поведение объекта при передаче его в процедуру. Рассмотрим простой пример:
В процедуре n() создается объект rp, затем он передается в процедуру n2() по значению (т.е. не по ссылке)... и опытным путем мы выясняем, что функция n2 работает не с копией этого объекта! Т.е. если написать так:
или так:
результат будет одинаковый. Получается, что Дельфи не копирует объекты, а передает их по ссылке?
Еще один аналогичный пример. И еще. Деструкторы в Дельфи не вызываются автоматически (например при выходе из процедуры)? |
||||||||
|
|||||||||
| DarkProg |
|
||||
![]() Законченный романтик ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1784 Регистрация: 11.3.2009 Где: Земля Репутация: 4 Всего: 19 |
И то и другое умеет делать. Я не понял если честно суть вашего эксперимента.
Нет и слава богу. Это же был бы бред... -------------------- "И твоя голова всегда в ответе за то куда сядет твой зад..." "Я студент - скажите с какого я ВУЗа..." |
||||
|
|||||
| boobie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Как работать с копией объекта? Как передать в функцию не ссылку на объект, а его копию? Что тогда произойдет с динамической памятью?
|
|||
|
||||
| DarkProg |
|
|||
![]() Законченный романтик ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1784 Регистрация: 11.3.2009 Где: Земля Репутация: 4 Всего: 19 |
Также. Передавать не указывая Var или Const, насколько я понимаю работу это и будет копия. Ничего с ней не должно быть, но при многократном выполнении подобной процедуры
Есть вероятность и не малая, что произойдёт порча памяти. Нужно обязательно указывать Const или Var. -------------------- "И твоя голова всегда в ответе за то куда сядет твой зад..." "Я студент - скажите с какого я ВУЗа..." |
|||
|
||||
| MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
Не путайте людей. Объект всегда передается по ссылке. Без вариантов. Копию объекта можно получить, если только предусмотреть для этого функцию типа Clone... в которой будет создан еще один объект и скопированы св-ва исходного. Это сообщение отредактировал(а) MetalFan - 13.10.2012, 15:19 -------------------- There are always someone smarter than you... |
|||
|
||||
| БелАмор |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 209 Регистрация: 10.6.2010 Где: Россия Репутация: 7 Всего: 17 |
Начиная с Delphi 7, язык Object Pascal стал называться так-же, как и среда разработки: Delphi. В объявлении класса не следует использовать ключевое слово var (кроме случаев, когда вы действительно хорошо знаете, что делаете). C var объявляется (если ничего не путаю) статическое поле (одно общее на все экземпляры класса), что требуется крайне редко. Насколько я понял, вы имеете опыт работы с С++. Когда я после C++ занялся изучением Delphi, я испытал культурный шок. В такой ситуации важно понять, что есть просто разные подходы, и все они имеют право на жизнь. И переходя в другую систему координат, нужно просто действовать в соотвествии с правилами, принятыми в этой ситеме. Остальное - дело привычки. Например, я некоторое время продолжал писать пустые скобки у функций при отутствии параметров, избегал пользоваться фигурными скобками для комментариев и т.д. Исходя из своего опыта в сходной ситуации, я позволю себе дать несколько комментариев на эту тему. В Delphi при отсутствии параметров как при объявлении, так и при вызове, скобки принято не писать. Первоначально это воспринимается как ломка устоявшихся привычек, однако, со временем понимаешь, что никаких особых проблем это не вызывает. В Delphi очень много подразумеваемых умолчаний. Одно из них: Все переменные классового типа являются указателями. Если в C++ есть два сполоба объявления:
то в Delphi есть только один:
При этом объявление (3) эквивалентно объявлению (2), т.е. SomeObject, хотя и не объявлен явно как указатель, является именно указателем. Зная это, вы можете логическим путём сделать все необходимые выводы. Полного эквивалента варианту объявления (1) в Delphi нет. Нечто похожее можно изобразить в новых версиях Delphi, в которых структура (record) может иметь методы, однако там есть куча ограничений и не следует пытаться заменить класс структурой просто из желания получить аналог объявления (1). Привыкнете к тому, что в Delphi всегда следует явно вызывать конструктор и деструктор (кроме случаев удаления компонента его владельцем или родителем). Заодно замечу, что в Delphi принято вызывать деструктор не напрямую, а через метод Free. Лично я считаю эту традицию крайне вредной, но идти против толпы не хочется. |
||||||
|
|||||||
| boobie |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 162 Регистрация: 16.9.2011 Репутация: нет Всего: нет |
Спасибо, теперь все понятно.
|
|||
|
||||
| lomaster |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 101 Регистрация: 27.5.2012 Репутация: нет Всего: 2 |
|
||||
|
|||||
| MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
И в чем разница? ну-ка просветите ка нас всех. желательно с примерами, демонстрирующими разницу. ccылка=указатель, разве нет? Добавлено @ 16:50 Путаешь. поле, общее для всех объектов описываемого класса объявляется с помощью class var. Никакого криминала в этом нет, вполне нормальное объявление:
Обоснуй плиз, интересно. Просто вывзов Free ограждает пользователя объекта от необходимости проверки на nil переменной, содержащей ссылку на объект. Это сообщение отредактировал(а) MetalFan - 14.10.2012, 16:54 -------------------- There are always someone smarter than you... |
|||
|
||||
| БелАмор |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 209 Регистрация: 10.6.2010 Где: Россия Репутация: 7 Всего: 17 |
Да, спасибо за поправку. Не стал уточнять в хелпе, потому и сделал оговорку по поводу "если ничего не путаю". Оказалось, не зря. Но и смысла в этом тоже никакого нет. Использовать var в объявлении класса имеет смысл только для явного прерывания секции class var (которая прерывается с появлением метода, свойства, ключевого слова var, или спецификатора видимости). Например, так:
А теперь прикинем, когда переменная может иметь значение nil: 1. Ей не присваивалось значение и это не локальная переменная. 2. Объект удалили и ссылку принудительно обнулили. Free используют постоянно, а часто ли обнуляют ссылки? При необнулении ссылок использование Free преврвщается в профанацию: Free не защищает ни от чего, даже просто от повторного вызова Free. Но у новичков в голове откладывается фраза "безопасное удаление" и приводит к непониманию ситуации и дальнейшим ошибкам. С непониманием этого момента приходится сталкиваться постоянно и давать пояснения вроде таких: http://www.delphikingdom.com/asp/answer.asp?IDAnswer=57952 Некоторые считают, что лучше всегда использовать FreeAndNil вместо Free. Апологетом такого подхода является, например, Александр Алексеев: http://www.gunsmoker.ru/2009/04/freeandnil-free.html Этот подход значительно более логичен, чем распространённая практика. Лично я считал бы правильным повседневно использовать Destroy, а при необходимости проверки на не-nil (а коли нужна проверка, то тут и обнуление в комплекте) - FreeAndNil. Однако объяснять каждый раз "почему Destroy, а не Free" - неэффективная трата времени. Поэтому я таки повседневно использую Free как дань традиции, а FreeAndNil - когда надо ещё и обнулить ссылку. |
||||||
|
|||||||
| northener |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1361 Регистрация: 2.9.2010 Репутация: 12 Всего: 20 |
И я тоже. P.S. Я только не понимаю причины, которые заставляют авторов ПО многократно использовать некоторую переменную для хранения ссылок на некоторый класс(форму), который многократно создают и уничтожают в течение работы программы. -------------------- Но только лошади летают вдохновенно. Иначе лошади разбились бы мгновенно! |
|||
|
||||
| northener |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1361 Регистрация: 2.9.2010 Репутация: 12 Всего: 20 |
А что ты скажешь о методе Release? -------------------- Но только лошади летают вдохновенно. Иначе лошади разбились бы мгновенно! |
|||
|
||||
| MetalFan |
|
|||
![]() Аццкий Сотона ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3815 Регистрация: 2.10.2006 Где: Moscow Репутация: 22 Всего: 128 |
Так это актуально только для форм... да и то имеет свои особенности, о которых не стоит забывать... -------------------- There are always someone smarter than you... |
|||
|
||||
| DarkProg |
|
|||
![]() Законченный романтик ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1784 Регистрация: 11.3.2009 Где: Земля Репутация: 4 Всего: 19 |
Ну надо смотреть от ситуации, но вот сделать типа такого: 1. Чего-то создать 2. Чего-то сделать 3. Разрушить это чего-то 4. Повторять пока не наступит что-то там Это неправильный подход, хотя на этапе предварительного тестирования и разработки весьма актуален, т.к. однозначно все переменные будут очищены и можно с уверенностью сказать что работает или не работает, а вот далее надо делать не разрушение, а очистку свойств чтобы заново использовать объект. Хотя есть ситуации когда надо именно разрушать объект. Иногда из-за некоторой ограниченности алгоритма или из-за принципа "надо здесь и сейчас и пофиг, что работает медленно". -------------------- "И твоя голова всегда в ответе за то куда сядет твой зад..." "Я студент - скажите с какого я ВУЗа..." |
|||
|
||||
| БелАмор |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 209 Регистрация: 10.6.2010 Где: Россия Репутация: 7 Всего: 17 |
Как тут уже упомянули, Release - это весьма частный случай, поскольку: 1. Применим только к формам. 2. Имеет смысл применять только к немодальным формам, в первую очередь MDIChild. По поводу Release, а также некоторым рядом лежащим вопросам (и не только) можно почитать по ссылке: http://forum.vingrad.ru/act-ST/f-331/t-308242.html Если пойти по приведённым там мной ссылкам и ссылкам по ссылкам, можно найти очень много интересного. Особо рекомендую это автору вопроса. Если пройдёте по моим ссылкам достаточно глубоко, особенно на delphikingdom, получится практически небольшой курс для начального въезжания в Delphi. Это сообщение отредактировал(а) БелАмор - 15.10.2012, 21:42 |
|||
|
||||
| northener |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1361 Регистрация: 2.9.2010 Репутация: 12 Всего: 20 |
Спасибо за ответ. -------------------- Но только лошади летают вдохновенно. Иначе лошади разбились бы мгновенно! |
|||
|
||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 18 Всего: 88 |
еще для прерывания секции type Добавлено через 3 минуты и 56 секунд
-------------------- Обижено школьников: 8 |
|||
|
||||
![]()
|
| Правила форума "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. |