Страница 2 из 3
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 02:42:41
Максим
Vapaamies писал(а):Смиялсо. Скажу вам по секрету: именно так работает TObject.Free.
То есть? В коде FPC там везде фигурирует Self, насколько я вижу.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 03:22:21
Vapaamies
TObject.Free по своей логике предназначен для вызова в том числе и для nil-объектов, для чего он вначале проверяет, не равен ли Self nil, после чего вызывает деструктор. Деструктор виртуален, и для него должна быть инициализирована VMT, что делается лишь при создании экземпляра.
Сермяжный смысл в том, что методы, не обращающиеся к полям объекта, вполне штатно можно вызывать и для неинициализированного экземпляра. Можно, например, написать свой аналог Free для реализации логики Ref/Release -- аналога умных указателей.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 04:20:31
Максим
Просто ваш комментарий подразумевал, что Free работает принципиально с неинициализированным объектом, хотя из кода этого не следует, а, как раз, напротив, он в этом случае ничего не делает. Резковато выразились?
Vapaamies писал(а):Сермяжный смысл в том, что методы, не обращающиеся к полям объекта, вполне штатно можно вызывать и для неинициализированного экземпляра.
Вы можете привести внятный пример, где это требуется (ведь имеется же class method, его использование и предлагалось топикстартеру)? Просто интересно.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 05:04:31
Vapaamies
Максим писал(а):Просто ваш комментарий подразумевал, что Free работает принципиально с неинициализированным объектом, хотя из кода этого не следует, а, как раз, напротив, он в этом случае ничего не делает.
Естественно. А что можно сделать с неинициализированным объектом? Но вызывается-то он в том числе и для
nil, и никакой мистики в TObject.Free нет. Это не магия компилятора, а просто реализованный в RTL метод, и любой программист может написать нечто похожее, если вдруг возникнет необходимость.
Максим писал(а):Резковато выразились?
Фраза, на которую я отвечал, звучала так:
NTFS писал(а):Потому что нет никакого смысла в вызове метода у несозданного объекта.
Пример TObject.Free как раз доказывает обратное: смысл есть, и один метод даже вызывается чуть менее, чем везде. Да, служебный TObject.Free -- особый случай. Но без какой бы то ни было магии, повторюсь. У рядового программиста может возникнуть потребность в своих служебных методах, и компилятор тут никаких препонов не ставит. ТС ведь именно это хотел выяснить?
Максим писал(а):Вы можете привести внятный пример, где это требуется
Боюсь,
мой пример не совсем внятный: TSharedObject.Ref и TSharedObject.Release -- как раз попытка сэмулировать разделяемые умные указатели. На чистом Паскале, к сожалению, LOCK XADD не напишешь, поэтому пришлось на ассемблере. Как бы то ни было, TSharedObject(
nil).Ref и TSharedObject(
nil).Release вызываются и не падают.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 05:09:22
Рождённый_в_СССР
Vapaamies
спс... извините что разбудил эту дискуссию, но nil^.nil^ - вы зря написали) хватило бы и одного ))) второй nil^ меняет тему )
хотя с другой стороны - я понял ошибку буквального перевода с этого языка Си++, за что Вам огромное спасибо!!!
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 05:13:20
Vapaamies
Vapaamies писал(а):Как бы то ни было, TSharedObject(nil).Ref и TSharedObject(nil).Release вызываются и не падают.
Забыл уточнить, что методы класса тут не подходят, потому как добавляются и освобождаются ссылки на конкретные объекты.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 06:08:11
alexey38
Конечно исходный пример просто содержал ошибку, но если сравнивать Паскаль и С++, то по практическому функционалу оба языка позволяют схожим образом написать что угодно, т.е. близки. Да, у С++ богаче библиотеки, тут ничего не поделаешь.
НО!!! FPC и Delphi позволяют элементарно просто отлавливать целую кучу мелких ошибок как на стадии компиляции, так и на стадии выполнения. Мой опыт и опыт моих коллег говорит о том, что программист на С++ пишет программу от начала до финала (отлаженный продукт) в несколько раз медленнее.
Это стабильно проявлялось и когда я сам писал на обоих языках, и у тех кто пишет только на Паскале или только на С++. При схожести задачи на Паскале результат получается намного раньше.
Конечно сейчас паскаль не контролирует указатели, а контролирует диапазоны, переполнение, а также изначально правильно написанные строки. А когда в 90-х была версия Borland Pascal 7, когда в режиме DPMI используя фишки защищенного режима процессора вся память (адресация в 16 битном режиме была сегмент + смещение) была нарезана на участки закрытые, для чтения и для записи. И любые ошибки адресации прямо в отладчике указывались на ошибочную строку. Вот тогда была сказка для начинающих программистов. Фактическая скорость программирования была еще выше, хотя был острый дефицит в готовых библиотеках.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 08:38:16
Brainenjii
Код: Выделить всё
program Project1;
Type
{ TFoo }
TFoo = Class
Private
Public
A: Integer; Static;
Class Procedure Bar;
End;
{ TFoo }
Class Procedure TFoo.Bar;
Begin
WriteLn('Hello World ', A, ' times');
End;
begin
TFoo.A := 10;
TFoo.Bar;
end.
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 15:22:37
Максим
Vapaamies писал(а):Но вызывается-то он в том числе и для nil
Где и кем вызывается?
Vapaamies писал(а):Забыл уточнить, что методы класса тут не подходят, потому как добавляются и освобождаются ссылки на конкретные объекты.
Не понял, ну добавляются и освобождаются, и что? Вы же сами писали:
Vapaamies писал(а):Сермяжный смысл в том, что методы, не обращающиеся к полям объекта, вполне штатно можно вызывать и для неинициализированного экземпляра.
Где отличие от методов класса в данном случае? Что мешает использовать ту же методику подсчёта ссылок?
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 17:02:53
Kemet
Vapaamies, а что у Вас там за проект Ono?
Re: один прикладной вопрос по ООП
Добавлено: 04.08.2012 17:56:56
AlexVinS
Надо в FAQ поместить:
1) class в С++ = object в FPC
2) class в FPC = class в java и c#, и не имеет(прямого) аналога в с++. (в основном, с точки зрения наличия неявного указателя)
3) а вот средства обобщенного программирования называется в FPC джененриками, но по сути является не аналогом дженериков из Явы и с#, а аналогом шаблонов из с++.
Re: один прикладной вопрос по ООП
Добавлено: 05.08.2012 00:04:50
Vapaamies
Kemet писал(а):Vapaamies, а что у Вас там за проект Ono?
Язык программирования -- "функциональный Паскаль" с декомпозицией и фракталами.
Re: один прикладной вопрос по ООП
Добавлено: 05.08.2012 15:05:25
debi12345
TObject.Free по своей логике предназначен для вызова в том числе и для nil-объектов, для чего он вначале проверяет, не равен ли Self nil,
Хотя реальная жизнь показывает, что полагаться на этут проверку нельзя - потому что неинициализированый указатель чаще всего не нулевой, а случайный > 0.
Re: один прикладной вопрос по ООП
Добавлено: 05.08.2012 17:47:45
Vapaamies
debi12345
В тех случаях, когда обработка такого указателя доходит до Free, -- явно что-то не то с логикой кода.
Нулями инициализируются глобальные переменные (при старте программы) и вновь созданные экземпляры классов (в прологе конструктора). Free предназначен именно для этих случаев. Чтобы корректно создавать и освобождать объекты по несколько раз во время выполнения, используется FreeAndNil, дополняющий Free.
А вот за локальными переменными, которые не инициализируются автоматом, нужно следить вручную. Тем более, что общее правило -- не выдавать созданные объекты наружу, и тогда блок создания-освобождения будет в пределах одной процедуры.
Плохой практикой также считается хранение объектов в массивах и записях. Объекты должны быть внутри объектов, и все будет в порядке.
Других случаев появления случайных указателей на объекты не припоминаю.
Re: один прикладной вопрос по ООП
Добавлено: 05.08.2012 17:58:59
Vadim
Рождённый_в_СССР писал(а):если уж Паскаль не видет смысла в вызове метода у не созданного объекта, почему он это компилирует?
Потому, что Паскаль до последней секунды надеется, что программист кончит маяться дурью и объект, наконец то, создаст. И когда его надежды оказываются тщетны, он гневно бъёт неразумного программиста AV'шником по голове.
