Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.77/26: Рейтинг темы: голосов - 26, средняя оценка - 4.77
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
Delphi 6-7

Теоретический пробел в TObject.Create

01.09.2023, 13:00. Показов 7407. Ответов 180
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветствую!

Возник у меня некий теоретический пробел по поводу конструктора TObject.Create.

C одной стороны, он ведет себя, как функция, возвращающая указатель на созданный экземпляр.
С другой стороны, сам Delphi считает его процедурой.
В хелпе указано, что TObject.Create выделяет память, но не инициализирует данные. Но память выделяет.
А в исходниках все тело конструктора состоит из begin/end.

Правильно ли я понимаю, что этот конструктор - что-то типа разновидности команды для препроцессора, где компилятор Delphi, встречая этот вызов, сам организовывает выделение памяти и возвращение адреса созданного экземпляра?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
01.09.2023, 13:00
Ответы с готовыми решениями:

Cannot convert 'void (_fastcall * (_closure )(TObject *,char &))(TObject *,char &)' to 'TKeyPressEvent'
доброго времени суток. роект был создан в builder 2007, а при попытке его скомпилировать на rad studio 2010 выдается ошибка: ...

Reverse for 'create' not found. 'create' is not a valid view function or pattern name
Всем привет, появилась проблема. Всё делал по инструкции, по итогу всё равно выбило ошибку: NoReverseMatch at / Reverse for 'create'...

TFilestream.create [cannot create file]
function bat: string; begin with TFileStream.Create(extractfilepath(application.ExeName)+'bin\gcc\bin\compile.bat', fmCreate) do ...

180
0 / 0 / 0
Регистрация: 02.09.2023
Сообщений: 27
07.09.2023, 17:09
Студворк — интернет-сервис помощи студентам
Да, был. Но, во-первых, constructor появился до введения классов. И при этом был процедурой. Во-вторых, он продолжает работать как процедура. В-третьих, сама Дельфи считает TObject.Create процедурой (это я цитирую сам себя, как и Вы, собственно). Посему приведённый ответ, как мне кажется, следует считать как минимум неточным, и уж точно - неудовлетворительным. А вообще, я ж уже говорил -
Цитата Сообщение от XpomAI Посмотреть сообщение
...это иллюстрация...
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
07.09.2023, 17:22  [ТС]
Цитата Сообщение от Rayvenor Посмотреть сообщение
Был ответ:
Цитата Сообщение от Rayvenor Посмотреть сообщение
введение классов в язык добавило и еще один вид функции - constructor
На что была дано от меня уточнение, что конструктор был еще в Borland Pascal, когда никаких классов и в помине не было, и вел себя абсолютно адекватно - был процедурой и инициализировал VMT.
0
462 / 185 / 32
Регистрация: 04.08.2018
Сообщений: 732
07.09.2023, 17:38
Цитата Сообщение от Constcat Посмотреть сообщение
Borland Pascal
Это другой ЯП. Не надо ожидать выполнение правил другого ЯП, вы обманываете себя.
0
пофигист широкого профиля
4770 / 3207 / 862
Регистрация: 15.07.2013
Сообщений: 18,615
08.09.2023, 02:26
Цитата Сообщение от Constcat Посмотреть сообщение
Хотя... Init, вроде тоже конструктор, а значение не возвращает.
Непорядок какой-то у этих всеблагих разрабов)))))
Никакого непорядка. Изначально Init это процедура для инициализации объекта давно созданного. Она не создаёт объект, но лишь инициализирует его поля заданными значениями. Собственно это же касается и конструктора Create.
Вот например.
Delphi
1
var MyClass : TMyClass;
Первый вариант:
Delphi
1
MyClass:=TMyClass.Create();
В этом случае компилятор предусматривает выделение памяти для этого конкретного экземпляра класса и возвращает ссылку на этот зкземпляр.
Второй вариант:
Delphi
1
MyClass.Create();
В этом случае никакая память не выделяется. Предполагается что она уже ранее выделена. И просто выполняется некая инициализация полей уже созданного экземпляра класса.

Добавлено через 2 минуты
Ну да. Это тоже магия компилятора.
Примите и прочь!
0
 Аватар для Beltar
1082 / 520 / 43
Регистрация: 05.05.2022
Сообщений: 3,719
08.09.2023, 06:47
Что-что, во 2-ом случае? А AV по чайнику? Класс со структурой не путайте.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 09:29  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
Класс со структурой не путайте.
О, я что-то пропустил, походу... В Delphi структуры появились? Или это так object/record называют?
0
пофигист широкого профиля
4770 / 3207 / 862
Регистрация: 15.07.2013
Сообщений: 18,615
08.09.2023, 10:55
Цитата Сообщение от Beltar Посмотреть сообщение
Что-что, во 2-ом случае? А AV по чайнику? Класс со структурой не путайте.
Читайте внимательно.
Цитата Сообщение от northener Посмотреть сообщение
Предполагается что она уже ранее выделена.
0
 Аватар для Beltar
1082 / 520 / 43
Регистрация: 05.05.2022
Сообщений: 3,719
08.09.2023, 11:19
Что значит, "предполагается"? Под класс память при объявлении не выделяется до вызова конструктора, под структуру выделяется.

За object из TP говорить не буду, не использовал. Полагаю, что там как в C++, где никаких классов нету, есть только объекты идентичные структурам, но тогда меня давно занимает вопрос, на фига все эти навороты в Delphi прикручивались к структурам версии так с 2005-ой, и что мешает просто уравнять object и record, сразу давая структурам еще и наследование.

Структура - это общеязыковой термин, а что там в Паскале их record назвали, это вопросы к дедуле Вирту.
0
пофигист широкого профиля
4770 / 3207 / 862
Регистрация: 15.07.2013
Сообщений: 18,615
08.09.2023, 11:27
Цитата Сообщение от Beltar Посмотреть сообщение
Что значит, "предполагается"?
Delphi
1
2
3
4
5
6
var MyClass : TMyClass;
 
  MyClass:=TMyClass.Create();
.... 
 
  MyClass.Create();
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 12:06  [ТС]
Цитата Сообщение от northener Посмотреть сообщение
Delphi
1
2
3
MyClass:=TMyClass.Create();
.... 
MyClass.Create();
С трудом понимаю логику, когда нужно повторно вызвать конструктор. Но ошибку не выдает, новую память, вроде, не выделяет.

Добавлено через 1 минуту
Цитата Сообщение от Beltar Посмотреть сообщение
Структура - это общеязыковой термин, а что там в Паскале их record назвали, это вопросы к дедуле Вирту.
Базовый класс, вроде, тоже общеязыковой термин был до недавнего времени... Ну, до тех пор, пока в Delphi его не переопределили, как "класс, наследуемый от TObject".
0
 Аватар для Beltar
1082 / 520 / 43
Регистрация: 05.05.2022
Сообщений: 3,719
08.09.2023, 13:52
В Delphi любой класс обладает всеми свойствами и методами TObject. Это логично, каждый класс должен что-то обязательно уметь, например, возвращать свое имя, записывать себя в виде человекочитаемой строки. И вообще о чем спор? В Delphi базовый класс называется TObject. В др. языке он может называться CClass, в 3-ем вообще никак. Но с точки зрения удобства проще, когда этот класс есть, и можно просто в справке посмотреть, например, инфу по TObject, а не по какому-то базовому классу. И такой класс можно явно объявить. Вот надо мне может его.

Но ошибку не выдает, новую память, вроде, не выделяет.
Наверное потому, что он видит отсутствие в выражении LValue. Хотя кодогенератор такую строку помечает, как не пустую. Не давая варнингов.

Добавлено через 42 минуты
А вообще по правилам Delphi можно игнорировать возвращаемое функцией значение, в конструкторе же, помимо неявного выделения памяти есть явные действия кодера. Можно, например, создать там файл, поместив его имя в одно из свойств класса. И тут уже возможен вариант, что может этот файл будет нужен и тогда экземпляр с его именем надо сохранить, а может записали и забыли, и соответственно не стали получать ссылку на экземпляр связанного с ним класса. Т. е. конструкция TMyClass.Create сама по себе может иметь смысл, компилятор же, не видя LValue, пропускает генерацию выделения памяти и возврата результата. Как с полями экземпляра быть внутри конструктора, мне непонятно, под них память запросить у ОС надо заранее, возможно, что она возвращается.

Ну и сама по себе цепочка конструкторов по inhereted, во-1, она, в отличие от Ц++ абсолютно произвольна, можно inherited в условие засунуть, во-2, а в какой момент там память выделяется? Очевидно, что все поля под которые надо выделить память, известны в момент вызова первого конструктора, от класса экземпляр которого создается. Цепочка же inhereted Create, если она есть, ничего выделять не должна, делая только то, что явно программист написал.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 14:29  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
Это логично, каждый класс должен что-то обязательно уметь, например, возвращать свое имя, записывать себя в виде человекочитаемой строки.
Я надеюсь, речь только о Delphi идет? Т.е., "каждый класс в Delphi"?
0
 Аватар для Beltar
1082 / 520 / 43
Регистрация: 05.05.2022
Сообщений: 3,719
08.09.2023, 16:01
Я не понимаю вопроса. В Delphi сделали так. Что базовый класс определен под именем TObject. Это ничем не отличается от того, что в стандарте языка определена, например, функция вычисления синуса. В Delphi существуют классовые ссылки из этого вытекает, что абсолютно любой класс в Delphi должен уметь себя идентифицировать.

Если в др. языке программирования аналог TObject явно не определен, но любой класс тоже имеет какой-то базовый функционал, то я не вижу никаких отличий от Delphi, более того, в Delphi можно и просто TMyClass=class написать, вообще не думая ни о каком TObject.

В чем вопрос-то? В отличиях класса от объекта и структуры?
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 16:30  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
В чем вопрос-то? В отличиях класса от объекта и структуры?
Один из вопросов был связан с тем, что считать "базовым классом".
В общеязыковом понимании, базовый класс - это класс, у которого нет предков, т.е., нет неявно прицепленного функционала, который цепляется паравозом ко всем классам-потомкам.
А самый первый вопрос (с которым уже разобрались) - что такое Create с точки зрения Object Pascal? Фактически являясь процедурой, ведет себя, как функция, несмотря на то, что в исходниках не возвращает никакого значения.
При этом такой же самый constructor, но уже применительно к object'у, ведет себя вполне ожидаемым образом.
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 21
08.09.2023, 16:50
Цитата Сообщение от Beltar Посмотреть сообщение
Структура - это общеязыковой термин
это просто термин из C
ничем он более не примечателен
Record ничуть не хуже, обозначает то же самое
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
08.09.2023, 17:44
Цитата Сообщение от Constcat Посмотреть сообщение
несмотря на то, что в исходниках не возвращает никакого значения.
То есть, наличие в исходнике вот этого:
Delphi
1
  TObject = class
тебя не смущает, учитывая, что неявно это интерпретируется/должно интерпретироваться, как:
Delphi
1
  TObject = class(TObject)
?
0
 Аватар для Beltar
1082 / 520 / 43
Регистрация: 05.05.2022
Сообщений: 3,719
08.09.2023, 17:45
1) Процедура это функция, не возвращающая обязательно результата.
void Proc(int a); В терминах Ц, как языка, вообще нет таких зарезервированных словОВ, как procedure и function. Да и в Delphi, я считаю, давно пора разрешить писать function F(A:Integer);

С др. стороны, void Proc(int a; int * b); И о ужас, она что-то в b может возвращать. А может и не возвращать, и вообще работать именно с указателем на b, по объяве не поймешь, но это проблема Ц, что в нем даже такие вещи, через ж*** сделаны. В Delphi я в таких случаях пишу out вместо var, если результат обязателен, т. е. переданная переменная будет изменена. Честно, не помню всех отличий м/у var и out. Так что это чисто культурный подход.

В Паскале значение функции надо было присваивать чему-то, в Delphi это убрали и использовать функцию, как процедуру возможно, особенно, если это какая-то фигня с результатом, которой неясно, что делать. Т. е. отличия уже условны.

Конструктор в Delphi возвращает ссылку на экземпляр, хотя есть и class constructor, т. е. он в терминах Паскаля является функцией. Но можно сказать, что это не процедура и не функция, а что-то иное. В юнитах, например, есть секции initialization/finalization, которые вообще непонятно что, но похожи на классовый конструктор с деструктором.

В общем, классифицировать можно по-разному, а о терминах договариваются.

Вопрос не в этом, а что мы вообще от языка хотим? Мы хотим, чтобы у нас абсолютно любой класс умел в некий набор действий, или мы хотим, чтобы у нас объект ТОЧКА, состоящий из вещественных значений координат X и Y сидел на стеке и занимал в памяти столько, сколько нужно для хранения этих 2 чисел?

Я по Object Pascal в редакции TP 7 лишь книжку читал во время учебы, в т. ч. про ООП, я помню, что там тоже было наследование, деление по доступу, но в общем-то всё. Возможно, что там все было реализовано без базового класса, т. е. фактически получался record, но с методами и добавлением полей и методов через наследование. Если п****, поправьте. Но я так понимаю, что в этом и есть разница м/у классами, которые большие, создаются в куче только при вызове конструктора, и доступны по ссылке и объектами, которые прям при объявлении создаются в памяти, и конструктор им нужен только для инициализации. В такой системе, как я понимаю, сделать тот же полиморфизм невозможно, т. к. все уже создано, или будет создано в стеке сразу при вызове, исходя из размеров объявленной переменой объекта.

Кто спец по Ц++ и его объектной модели, может пояснить, как они там с этим живут.
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
08.09.2023, 17:46
Я уже давно принял тот факт, что многое из того, что якобы описано в модуле System.pas - является магией компилятора.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 18:18  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
С др. стороны, void Proc(int a; int * b); И о ужас, она что-то в b может возвращать. А может и не возвращать, и вообще работать именно с указателем на b, по объяве не поймешь, но это проблема Ц
Это не то же самое. Void ничего не возвращает, а во-вторых, вы, скорее всего, перепутали int *b с int &b, где b передается в процедуру по ссылке (то же самое, что и (var b: integer) в Delphi).

И по объявлению все понятно - void - аналог паскалевского procedure, признак функции - это явное указание типа.
Цитата Сообщение от Beltar Посмотреть сообщение
Кто спец по Ц++ и его объектной модели, может пояснить, как они там с этим живут.
Я как раз по c++ и его объектной модели. Там своих заморочек хватает, но базовый класс там не тянет никакого паравоза.

Цитата Сообщение от Beltar Посмотреть сообщение
В Паскале значение функции надо было присваивать чему-то, в Delphi это убрали и использовать функцию, как процедуру
В Паскале это тоже было. Регулировалось опцией компилятора $X и называлось Extended Syntax.

Цитата Сообщение от Beltar Посмотреть сообщение
Возможно, что там все было реализовано без базового класса, т. е. фактически получался record, но с методами и добавлением полей и методов через наследование.
Совершенно верно.

Цитата Сообщение от Beltar Посмотреть сообщение
В такой системе, как я понимаю, сделать тот же полиморфизм невозможно, т. к. все уже создано, или будет создано в стеке сразу при вызове, исходя из размеров объявленной переменой объекта.
Конструктор в старой модели object как раз занимался тем, что инициализировал VMT, т.е., если предполагались виртуальные методы, то конструктор был обязателен. Если нет - то можно было и без него.
0
 Аватар для Beltar
1082 / 520 / 43
Регистрация: 05.05.2022
Сообщений: 3,719
08.09.2023, 18:32
Цитата Сообщение от Constcat Посмотреть сообщение
вы, скорее всего, перепутали int *b с int &b
Легко, я уже не помню, когда последний раз с Ц соприкасался. От связанных с ним воспоминаний "минЕ аж трИсёт".

Цитата Сообщение от Constcat Посмотреть сообщение
void - аналог паскалевского procedure, признак функции - это явное указание типа
Там просто термина такого нет "процедура". Есть только функция, которая ничего не возвращает.

Цитата Сообщение от Constcat Посмотреть сообщение
Конструктор в старой модели object как раз занимался тем, что инициализировал VMT, т.е., если предполагались виртуальные методы, то конструктор был обязателен.
И как это работало? Ну т. е. в какой момент становилось понятно, что родилось, подо что выделять память, и что искать в VMT? И как оно в Си++ работает?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.09.2023, 18:32

how can i create mainmenu with any fonts wich i wont and how can i create mainmenu with diferent style?
please tell me how can i create mainmenu with any fonts wich i wont and how can i create mainmenu with diferent style?

CREATE SEQUENCE - ошибка синтаксиса в "CREATE"
Выполняю некоторое задание по вузу, в ERBuilder создаются таблицы, связи между ними задаются, добавляются последовательности(или триггеры),...

Каждую группу из n последовательно стоящих символов ‘’ (пробел) и '\t' (табуляция) заменить на один пробел
Каждую группу из n последовательно стоящих символов ‘’ (пробел) и '\t' (табуляция) заменить на один пробел

В строке заменить пробел между слов на запятую и пробел
В строке заменить пробел между слов на запятую и пробел

Заменить неразрывный пробел NBSP на обычный пробел в файле
здравствуйте написал скрипт: with open('russianSpeaking.js', 'r', encoding='utf-8') as f: # чтение из файла f_text = f.read() ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru