Теоретический вопрос по ООП

Вопросы программирования на Free Pascal, использования компилятора и утилит.

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

Иван

Сообщение Иван »

Если необходимо конструктор вызывать руками

Код: Выделить всё

type TSomeClass = class
    constructor init;
    procedure SomeProcedure;
    ...
  end;

...

var
  c : TSomeClass;
begin
  c.init;
  ...
end.


зачем тогда такое "гордое" объявление

constructor init;

Можно же писать

procedure init;

и с тем-же успехом ее вызывать.
Какая между ними разница?
Boriss
незнакомец
Сообщения: 8
Зарегистрирован: 31.08.2005 15:17:34

Сообщение Boriss »

Дело в том, что срабатывает объявление constructor - это особая "процедура", которая строит для объектов особые таблицы VMT (Virtuel Method Table), таблицу динамических методов (процедур и функций объекта). Отсюда и название "построитель"
Виртуальные методы вызываются в выполняемом файле (не в исходном тексте программы!) по адресу, который хранится в такой таблице. Если ее нет, то при вызове виртуального метода (без предшествующего вызова констрактора) идет обращениу к той области памяти, где она должна быть и где должен быть адрес процедуры, а там ... - в лучшем случае получите "Программа выполнила недопустимую операцию...". Хуже, если начнет что-то делать! Но что?
Аналогично, закончив работу класса (объекта) нужно оную таблицу удалить. Делает это "особая" поцедура destructor.
ОБЕ МОГУТ НИЧЕГО БОЛЬШЕ НЕ ДЕЛАТЬ! Срабатывает объявление constructor, destructor! Дополнительный код для обеспечения такой работы писать самому не надо. Функциональнось добавляем им для экономии, чтобы не писать других методов
Guest

Сообщение Guest »

Понятно, доступно. Спасиба огромное.

Конструктор который создает объект обязательно называется create или нет?
Boriss
незнакомец
Сообщения: 8
Зарегистрирован: 31.08.2005 15:17:34

Сообщение Boriss »

Нет, конечно. Это в Delphi сложилась такая традиция. В Borland Pascal называли Init. В С++ констрактор называется именем класса (если его не создаешь сам, то такой создает компилятор), а дестрактор, кстати называется ~<имя класса>.
Кстати, констракторов, как и дестракторов можешь заводить сколько хошь
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

[code]var
c : TSomeClass;
begin
c.init;


Access Violation обеспечен, однако...
Аватара пользователя
pda
постоялец
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение pda »

Иван Шихалев писал(а):
[code]var
c : TSomeClass;
begin
c.init;


Access Violation обеспечен, однако...

Вряд ли... Выше по треду Init - статический метод (конструктор), а их можно вызывать не создавая экземпляры объекта. (Фактически - вызов конструктора от типа (TSomeClass.Init) - оно и есть). Другое дело, что в Object Pascal динамическими (в BP названиях) объектами, после такого вызова, созданный объект перейдёт в разряд утечек памяти... ;-)
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

Переменная "c" не инициализирована.
Аватара пользователя
pda
постоялец
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение pda »

Иван Шихалев писал(а): Переменная "c" не инициализирована.

И? Специально сел и проверил явно в FPC. Написал программу. Выполняется. Никаких A/V.

Код: Выделить всё

{$MODE OBJFPC}
type
  TSomeClass = class
  public
    constructor Init;
  end;

constructor TSomeClass.Init;
begin
  inherited;
end;

var
  c: TSomeClass;
begin

c.Init;

writeln('OK');
ReadLn;
end.
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

А теперь попробовать что-нибудь с объектом "c" сделать - не метод класса.
Boriss
незнакомец
Сообщения: 8
Зарегистрирован: 31.08.2005 15:17:34

Сообщение Boriss »

Иван Шихелев имеет в виду, что с классами нужно работать не как в BP, а как в delphi

Код: Выделить всё

{$MODE ObjFPC}
type
   TSomeClass = class
   constructor Init;
   procedure SomeP; virtual;
   destructor done; virtual;
   end;

constructor TSomeClass.Init;
begin Inherited end;

procedure TSomeClass.SomeP;
begin
  WriteLn('SomeP');
end;

destructor TSomeClass.Done;
begin Inherited end;

var
 c: TSomeClass;
begin
  c:=TSomeClass.Init;
  c.SomeP;
  c.Done;
end.
Boriss
незнакомец
Сообщения: 8
Зарегистрирован: 31.08.2005 15:17:34

Сообщение Boriss »

Да, только надо указывать, какого класса Create
GDBPASW.exe - работа с ним такая же, как с GDB - есть описание на сайте
Что не понятно будет - пиши, ибо возможности его огромны. Я с ним познакомился при работе с GCC на С
ДА!!! Работать с ним лучше из FAR'а. ИМХО
Аватара пользователя
pda
постоялец
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение pda »

Иван Шихалев писал(а): А теперь попробовать что-нибудь с объектом "c" сделать - не метод класса.

Что именно сделать-то надо, что значит сделать не метод класса? Объект не создан - значит, что не выделена память под поля объекта, нет записей в VMT и Self содержит мусор (а может и nil - не проверял). На работоспособность статических методов это не влияет.
Аватара пользователя
pda
постоялец
Сообщения: 303
Зарегистрирован: 27.05.2005 19:59:53

Сообщение pda »

Иван писал(а): причем вызов типа

Код: Выделить всё

c.Create;

не сработает так как объекта еще нет.
Верно?

Отлично сработает. Только результат работы (созданный экземпляр объекта) уйдёт в никуда, ведь ты его не сохраняешь...
Аватара пользователя
Иван Шихалев
энтузиаст
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург
Контактная информация:

Сообщение Иван Шихалев »

На работоспособность статических методов это не влияет.

При условии, что они не вызывают виртуальных и не обращаются к данным объекта... А нафиг они такие нужны?
GrayEddy
постоялец
Сообщения: 375
Зарегистрирован: 06.05.2005 09:37:56

Сообщение GrayEddy »

> Boriss
Где взять GDBPASW.exe? Гугль не предложил его скачать. Хотя искал по "gdbpas"
Настолько я понял, это gdb, заточенный под гну паскаль.
Ответить