вопрос по ООП

Общие вопросы программирования, алгоритмы и т.п.

Модератор: Модераторы

вопрос по ООП

Сообщение Фишер » 24.10.2014 00:47:04

Мир дому Вашему), подскажите есть ли разница и если есть, то в чём между этими двумя вариантами:
Код: Выделить всё
type
  TMyClass = class
    constructor test;
end;

constructor TMyClass.test;
begin
  WriteLn('Hello world!');
end;

begin
  TMyClass.test;
end.   

Код: Выделить всё
type
  TMyClass = class
    procedure test;
end;

procedure TMyClass.test;
begin
  WriteLn('Hello world!');
end;

begin
  TMyClass(nil).test;
end.
Фишер
незнакомец
 
Сообщения: 2
Зарегистрирован: 24.10.2014 00:43:17

Re: вопрос по ООП

Сообщение Vapaamies » 24.10.2014 12:39:10

Оба варианта неверны, конструктор вызывается не так. В первом примере теряется указатель на вновь созданный конструктором объект, а во втором к этому добавляется потенциальный AV, если конструктор не только выводит сообщение в консоль, но и обращается к данным объекта.
Аватара пользователя
Vapaamies
постоялец
 
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург

Re: вопрос по ООП

Сообщение daesher » 25.10.2014 20:46:59

Vapaamies писал(а):Оба варианта неверны, конструктор вызывается не так. В первом примере теряется указатель на вновь созданный конструктором объект, а во втором к этому добавляется потенциальный AV, если конструктор не только выводит сообщение в консоль, но и обращается к данным объекта.

Я бы сказал иначе: первый формально допустим, но порождает "мусор" (и будет вполне приемлемым, если этот мусор будет где-нибудь и как-нибудь отлавливаться, например, при вызове конструктор зарегистрирует создаваемый объект в каком-нибудь списке), второй принципиально неверный - вызывается метод несозданного объекта. А вот если оформить метод из второго варианта как class procedure, и вызвать его как в первом варианте, то всё будет верно.
С точки зрения генерации кода разница есть. С точки зрения поведения именно такого кода - в первом (формально верном) случае появится мусор (но если больше в программе ничего не будет, то он так же успешно и уничтожится с окончанием программы), во втором мусора не будет, хотя в метод и будут переданы принципиально неверные и опасные параметры - нулевой указатель вместо self. IMHO второй вариант собственно к ООП отношения не имеет, это - всего лишь "хак", позволяющий его обойти.

Добавлено спустя 21 минуту 15 секунд:
Хотя вполне допускаю, что такой хак кому-то когда-то может понадобиться. Например, есть какой-то набор очень неплохих модулей, где в каком-то классе, помимо всего прочего, есть и нужный нам метод. Создать объект из этого класса мы не можем или не хотим - и тогда (и только тогда), если этот метод вдруг не работает с полями, VMT и прочим - его можно вызвать так. Если такая работа некритична для нашей функциональности - можно ему подсунуть не nil, а пустой буфер.
daesher
постоялец
 
Сообщения: 221
Зарегистрирован: 09.03.2010 22:17:14

Re: вопрос по ООП

Сообщение stanilar » 27.10.2014 19:08:38

Разница в них только в том, что Вы хотели получить.

daesher писал(а):второй вариант собственно к ООП отношения не имеет

Он имеет отношение к работе с классами. И в ООП может быть очень просто применен:

Код: Выделить всё
procedure Test(b : boolean);
var
  Obj : TObject
begin
  Obj := nil
  if b then Obj := TObject.Create;
  Obj.Free; // try except не нужен 
end;


Можете воспринимать такой подход как способ писать виртуальный код.
stanilar
постоялец
 
Сообщения: 289
Зарегистрирован: 09.03.2010 19:09:02


Вернуться в Общее

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 19

Рейтинг@Mail.ru