Создание объектов, приватный конструктор

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

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

Создание объектов, приватный конструктор

Сообщение Rand » 05.11.2012 17:16:43

Добрый день! Поясните пожалуйста несколько моментов:

1.
Код: Выделить всё
var obj: TFoo;
begin
  obj.Bar;
end;

Почему я могу вызывать метод объекта, который не был создан? Ведь если в методе будет попытка обращения с свойствам класса, я получу SIGSEGV. Есть ли данной особенности полезное применение?

2.
Код: Выделить всё
var obj: TFoo;
begin
  obj := TFoo.Create;
  obj.Bar;
end;

При объявлении конструктора, как private constructor Create; компилятор проглатывает данный код, игнорируя код конструктора, вместо того, чтобы выдать error, как это делается на приватных методах. При этом сам объект, как я понимаю, создается. Почему?
Rand
незнакомец
 
Сообщения: 4
Зарегистрирован: 05.11.2012 15:23:30

Re: Создание объектов, приватный конструктор

Сообщение Brainenjii » 05.11.2012 20:45:09

1. Вы сможете обращаться к полям, с установленным флагом Static. А вообще, это Warning.
2. У всех наследников от TObject уже есть публичный конструктор Create, если вы "перекрыли" его в приватной секции, то "перекрыт" он окажется только для того модуля, в котором объявлен. Соответственно, если вы инициализируете поля класса в "перекрытом" конструкторе, то при вызове публичного конструктора по умолчанию они инициализированы не будут.
Как-то так
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Создание объектов, приватный конструктор

Сообщение Rand » 05.11.2012 23:25:11

Спасибо за ответ, Brainenjii! Извините, возможно тему следовало создать в разделе "Обучение Free Pascal". Позволю себе задать ещё пару глупых вопросов:
1. Про конструктор. Посмотрел реализацию Singleton, получается, что единственный способ перекрыть родительский конструктор - создать метод не-конструктор с тем же именем?
2. По первому вопросу: Я ведь могу TFoo.StaticField сразу использовать, вместо того, чтобы переменную инициализировать? В общем, пока-что сомнительная фича для меня =)

Возможно, посоветуете что почитать непосредственно про объектную модель в Object Pascal? Буду благодарен.
Rand
незнакомец
 
Сообщения: 4
Зарегистрирован: 05.11.2012 15:23:30

Re: Создание объектов, приватный конструктор

Сообщение Vadim » 06.11.2012 03:00:07

Есть классы, которые всегда динамические и переменные которых надо всегда cоздавать. И есть объекты, которые могут быть как динамические, так и статические, которые остались в наследство от Turbopascal.
Что именно Вы имели в виду в своём посте?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: Создание объектов, приватный конструктор

Сообщение SSerge » 06.11.2012 05:29:16

Rand писал(а):получается, что единственный способ перекрыть родительский конструктор - создать метод не-конструктор с тем же именем?


Единственный способ перекрыть родительский конструктор - создать в дочернем классе конструктор с тем же именем. Процедурой не перекроете, ибо она просто будет существовать отдельно. В отличие от С++ и многих других языков, в Object Pascal вы в конструкторе вручную управляете вызовом конструкторов предыдущего класса, и если его не вызовете... то и не вызовете - на ваше усмотрение. Что формально нарушает принципы ООП и позволяет порождать совершенно кошмарные и нелогичные зависимости между классами, если такового захочется. Точно так же с деструкторами - не вызвали родительский - значит ваше исключительное решение, почему этого не сделали. :D Принуждения никакого.

Статические методы можете рассматривать как обычные процедуры, именованно привязанные к какому-нибудь классу. Общаться с какими либо нестатическими полями экземпляра класса они не должны (и не могут).
SSerge
энтузиаст
 
Сообщения: 971
Зарегистрирован: 12.01.2012 05:34:14
Откуда: Барнаул

Re: Создание объектов, приватный конструктор

Сообщение Vapaamies » 06.11.2012 10:31:12

Rand писал(а):Почему я могу вызывать метод объекта, который не был создан?

Было.

Rand писал(а):При объявлении конструктора, как private constructor Create; компилятор проглатывает данный код, игнорируя код конструктора, вместо того, чтобы выдать error, как это делается на приватных методах. При этом сам объект, как я понимаю, создается. Почему?

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

Re: Создание объектов, приватный конструктор

Сообщение PapaNT » 07.11.2012 16:37:23

Можно в тему задать уточняющий вопрос?

Если, к примеру, на форме, создаю какой-либо визуальный элемент, хоть label... То надо ли вызывать на него деструктор?
PapaNT
постоялец
 
Сообщения: 167
Зарегистрирован: 11.09.2009 12:06:46
Откуда: Москва

Re: Создание объектов, приватный конструктор

Сообщение Light13 » 08.11.2012 08:10:16

to PapaNT Если вы его создали и не указали владельца
Код: Выделить всё
  MyLabel := TLabel.Create(nil);


Тогда нужно.
В противном случае его уничтожением должен заниматься владелец
Аватара пользователя
Light13
постоялец
 
Сообщения: 127
Зарегистрирован: 17.07.2009 07:50:10
Откуда: Челябинск

Re: Создание объектов, приватный конструктор

Сообщение Rand » 08.11.2012 17:59:45

SSerge писал(а):Единственный способ перекрыть родительский конструктор - создать в дочернем классе конструктор с тем же именем

Ну это понятно, я имел ввиду, что если в родительском классе конструктор назван Create, а в дочернем я напишу class function с именем Create и конструктор сделаю приватным, то пользователь класса не сможет вызвать конструктор?
Vapaamies писал(а):Было.

Спасибо.
Rand
незнакомец
 
Сообщения: 4
Зарегистрирован: 05.11.2012 15:23:30

Re: Создание объектов, приватный конструктор

Сообщение Vapaamies » 08.11.2012 19:01:44

SSerge писал(а):Единственный способ перекрыть родительский конструктор - создать в дочернем классе конструктор с тем же именем.

Если в родительском классе есть несколько перегруженных конструкторов, их можно будет вызвать в любом случае.

Rand писал(а):в дочернем я напишу class function с именем Create и конструктор сделаю приватным

Зачем?! Конструктор -- и так функция класса, разве что с особым смыслом.
Аватара пользователя
Vapaamies
постоялец
 
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург

Re: Создание объектов, приватный конструктор

Сообщение Rand » 08.11.2012 19:49:30

Vapaamies писал(а):Зачем?! Конструктор -- и так функция класса, разве что с особым смыслом.

Для вот этого
Rand
незнакомец
 
Сообщения: 4
Зарегистрирован: 05.11.2012 15:23:30

Re: Создание объектов, приватный конструктор

Сообщение Brainenjii » 08.11.2012 19:53:56

А чем Вас не устраивает засунуть в переопределённый стандартный конструктор исключение, как предлагается в Вами же приведённой ссылке?
Аватара пользователя
Brainenjii
энтузиаст
 
Сообщения: 1351
Зарегистрирован: 10.05.2007 00:04:46

Re: Создание объектов, приватный конструктор

Сообщение Vapaamies » 08.11.2012 20:47:23

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

Re: Создание объектов, приватный конструктор

Сообщение Иван Шихалев » 10.12.2012 00:44:47

Rand писал(а):Почему я могу вызывать метод объекта, который не был создан?

Потому что компилятор «не знает» был ли этот объект создан. Для него ничего не создано, поскольку создание объектов происходит в run-time. Он лишь знает, что переменная соответствующего типа определена. Компилятор, конечно, может предполагать из контекста, что вызывается метод неинициализированной переменной, ну так он так и делает, выдавая предупреждение.
Аватара пользователя
Иван Шихалев
энтузиаст
 
Сообщения: 1138
Зарегистрирован: 15.05.2006 11:26:13
Откуда: Екатеринбург


Вернуться в Free Pascal Compiler

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

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

Рейтинг@Mail.ru