Страница 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'шником по голове. :)