Страница 1 из 1

вопрос по ООП

СообщениеДобавлено: 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.

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

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

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

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

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

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

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

СообщениеДобавлено: 27.10.2014 19:08:38
stanilar
Разница в них только в том, что Вы хотели получить.

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

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

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


Можете воспринимать такой подход как способ писать виртуальный код.