Форум программистов, компьютерный форум, киберфорум
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. Показов 7152. Ответов 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
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 18:39  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Beltar Посмотреть сообщение
И как это работало? Ну т. е. в какой момент становилось понятно, что родилось, подо что выделять память, и что искать в VMT?
Я сейчас точно не вспомню, там целая идея была с "поздним связыванием".
По большому счету, компилятор на этапе сборки уже отлично знает про все виртуальные методы и их вызовы. Поэтому вызов конструктора, скорее всего, просто приводил к заполнению таблицы VMT уже собранной информацией.

Цитата Сообщение от Beltar Посмотреть сообщение
И как оно в Си++ работает?
Да примерно так же.
0
 Аватар для Beltar
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,662
08.09.2023, 18:45
А если конструктор по условию вызывается?
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 19:02  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
А если конструктор по условию вызывается?
Насколько я помню, тупо не работал полиморфизм (не вызывались методы потомков).
0
 Аватар для krapotkin
6854 / 4680 / 1465
Регистрация: 14.04.2014
Сообщений: 20,686
Записей в блоге: 21
08.09.2023, 19:05
ну вот же вариант вызова конструктора по классу, в самом начале программы
и компилятор не знает что класть в result до вызова
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
TFormClass = class of TForm;
 
TForm1 = class(TForm)
end;
 
TForm2 = class(TForm)
end;
 
function CreateForm(AClass : TFormClass) : TForm;
begin
  result := AClass.Create(Application) ;
end;
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 19:17  [ТС]
Цитата Сообщение от krapotkin Посмотреть сообщение
ну вот же вариант вызова конструктора по классу, в самом начале программы
и компилятор не знает что класть в result до вызова
Почему не знает? Где-то же по тексту программы есть вызов этой функции уже с передачей конкретного параметра конкретного типа. Вот оттуда он и знает.
0
 Аватар для Beltar
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,662
08.09.2023, 19:25
Э-э... Передавая классовую ссылку мы прямым текстом говорим, что за класс брать. В этом суть классовых ссылок.

А Result на этапе компиляции просто размечается, как ссылка. Это ничем не отличается от превентивного объявления указателя на еще необъявленный тип, или уточнений, что TMyClass=class в начале юнита.
0
0 / 0 / 0
Регистрация: 02.09.2023
Сообщений: 27
08.09.2023, 22:55
Цитата Сообщение от northener Посмотреть сообщение
Изначально Init это процедура для инициализации объекта давно созданного.
Изначально - это где и когда? Помню Init-ы только как конструкторы ещё в паскалевских библиотеках типа TurboVision-а.

Цитата Сообщение от northener Посмотреть сообщение
Предполагается что она уже ранее выделена.
Вообще, пример интересный. Проблемка в том, что хотелось бы увидеть альтернативный способ предварительного выделения под экземпляр класса памяти. Если есть, милости просим, очень хочется посмотреть. Эта мысль была, когда читал. К моменту написания уже кой-чего попробовал, вроде получается. У TObject-а есть метод NewInstance - хелп утверждает, что он автоматически вызывается из конструктора.
Delphi
1
2
MyVar := MyType.NewInstance;
MyVar.Create;
Компилятор съел. Возможно нужны ещё какие-то телодвижения...
Похоже, что очередной фокус Копперфильда разоблачён. ))) Так что, мы, с Вашего позволения, ещё немного побудем. )))

Но это не отменяет вопроса, если есть свой вариант, было б очень интересно.

Цитата Сообщение от Beltar Посмотреть сообщение
что мешает просто уравнять object и record, сразу давая структурам еще и наследование.
Зачем? Опять городить не нужный хлам. Есть объекты - забирайте свою инкапсуляцию, а есть структуры/записи - это чистые данные, без дополнительного прицепа. Оставьте Кесарю кесарево - не изобретайте лишних сущностей. )))

Цитата Сообщение от Beltar Посмотреть сообщение
Наверное потому, что он видит отсутствие в выражении LValue. Хотя кодогенератор такую строку помечает, как не пустую. Не давая варнингов.
Нет. Ошибка возникала при выполнении. Скорее это потому, что переменная не nil. Кстати, нужно будет попробовать записать неё что-то с потолка. Обругается, но интересно как? ))))

Цитата Сообщение от Beltar Посмотреть сообщение
Ну и сама по себе цепочка конструкторов по inhereted
Не, ну какие inhereted-ы? Мы не смогли стартануть Последний конструктор, до вызов предыдущих даже не дошло. Так что, да, сначала подать память, потом конструктор и всё остальное.

Добавлено через 5 минут
Цитата Сообщение от krapotkin Посмотреть сообщение
это просто термин из C
ничем он более не примечателен
Record ничуть не хуже, обозначает то же самое
Совершенно верно. Дедушка Вирт, конечно классный, но записи поцупал толь у Кобола, толь у Алгола. ))))) Кобол был раньше и у него были record-ы. А Си со структурами посетили нас попозже. Так что, рекОрд за рЕкордами. ))))

Добавлено через 9 минут
Цитата Сообщение от AzAtom Посмотреть сообщение
То есть, наличие в исходнике вот этого:
DelphiВыделить код
1
  TObject = class
тебя не смущает, учитывая, что неявно это интерпретируется/должно интерпретироваться, как:
DelphiВыделить код
1
  TObject = class(TObject)
А почему это должно смущать? В хелпе сказано, что первая форма равносильна второй. По этому, с одной стороны, запрет на второе для TObject непротиворечив (замена/подстановка не требуется), что TObject уже определён, а любое другое имя класса - уже будет наследник. А свой базовый класс нам магия не позволяет. )))))
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
08.09.2023, 23:03  [ТС]
Цитата Сообщение от XpomAI Посмотреть сообщение
Delphi
1
2
MyVar := MyType.NewInstance;
MyVar.Create;
Т.е., сначала выделяем память через NewInstance, а затем еще раз, но уже из Create?
Но походу, это почти то же самое, что было приведено выше
Delphi
1
2
MyVar:=MyType.Create;
MyVar.Create;
0
0 / 0 / 0
Регистрация: 02.09.2023
Сообщений: 27
08.09.2023, 23:55
Цитата Сообщение от Beltar Посмотреть сообщение
Я по Object Pascal в редакции TP 7 лишь книжку читал во время учебы, в т. ч. про ООП, я помню, что там тоже было наследование, деление по доступу, но в общем-то всё. Возможно, что там все было реализовано без базового класса, т. е. фактически получался record, но с методами и добавлением полей и методов через наследование. Если п****, поправьте. Но я так понимаю, что в этом и есть разница м/у классами, которые большие, создаются в куче только при вызове конструктора, и доступны по ссылке и объектами, которые прям при объявлении создаются в памяти, и конструктор им нужен только для инициализации. В такой системе, как я понимаю, сделать тот же полиморфизм невозможно, т. к. все уже создано, или будет создано в стеке сразу при вызове, исходя из размеров объявленной переменой объекта.
Object Pascal тогда ещё Борланды не освоили. Это был просто паскаль (турбо или борланд).

Там было вполне полноценное ООП, object и record - две большие разницы, а полиморфизм цвёл в полный рост. Не стоит хаять добротно собранную систему. ))
По поводу классов и обжектов, тоже не стоит так примитизировать. Размер object-а ограничивался только возможностями ОС. Никто не запрещал создавать их в куче, со всеми вытекающими. А конструктор - да, был необязателен, если Вы не пользовались виртуальными методами, но зачем тогда... но это уже совсем другая история. Принципиально - всё было возможно. )))

Да! Как я мог забыть! Базовый класс определялся самим программером, как самый старший предок в иерархии. И их могло быть больше одного.

Цитата Сообщение от Beltar Посмотреть сообщение
Процедура это функция, не возвращающая обязательно результата.
Согласитесь, если процедуру определять таким образом, то функцию можно определить, как процедуру, обязательно возвращающую результат. Нет?

Добавлено через 57 секунд
Цитата Сообщение от Beltar Посмотреть сообщение
А если конструктор по условию вызывается?
Это как?

Добавлено через 7 минут
Цитата Сообщение от Constcat Посмотреть сообщение
Т.е., сначала выделяем память через NewInstance, а затем еще раз, но уже из Create?
Но походу, это почти то же самое, что было приведено выше
Нет. Второе прогонит код Create-а два раза (рукописный). Но при этом не будут отработаны какие-то автоматические штучки. Магия проследит. )))
В первом случае мы вызываем штатный class method TObject-а, который всё равно был бы вызван при "нормальном" вызове Create-а, а теперь, возможно будет проигнорирован Магией.

Честно сказать, я не знаю. Мне это пришло в голову и было опробовано пару часов назад, дальше этого я не пошёл. Решил потрепаться на форуме. )))

Добавлено через 14 минут
Цитата Сообщение от Beltar Посмотреть сообщение
И как это работало? Ну т. е. в какой момент становилось понятно, что родилось, подо что выделять память, и что искать в VMT? И как оно в Си++ работает?
Например, такая конструкция:

Delphi
1
MyVar := New (MyType, MyConstructor);
MyVar - переменная-указатель на необходимый тип или любой тип-предок.
MyType - необходимый тип.
Второй параметр, понятное дело, конструктор. Любой доступный в MyType.
Были ещё варианты с тем, что в Си называется кастомизацией, кажется. Ещё какая-то экзотика. Я сейчас уж и не помню на вскидку.

Добавлено через 5 минут
Цитата Сообщение от Constcat Посмотреть сообщение
выделяем память через NewInstance
Кстати, я забыл главное сказать. NewInstance - виртуальный. То есть можно подшаманить и своя система выделения памяти уже не так призрачна. ))))

Добавлено через 13 минут
Цитата Сообщение от XpomAI Посмотреть сообщение
А почему это должно смущать? В хелпе сказано, что первая форма равносильна второй. По этому, с одной стороны, запрет на второе для TObject непротиворечив (замена/подстановка не требуется), что TObject уже определён, а любое другое имя класса - уже будет наследник. А свой базовый класс нам магия не позволяет. )))))

Извините, кусочек текста потерялся. ))))) Я хотел сказать, что с другой стороны такая "рекурсия" вполне может быть допустима, и проверить мы это не можем, так как нам не удастся осуществить такое описание TObject = class(TObject) потому, что TObject уже определён.
0
 Аватар для Beltar
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,662
09.09.2023, 00:32
Borland Pascal стал Object Pascal в версии 5.5. Т. е. они подцепили ООП и даже версию мажорную не сменили.

Цитата Сообщение от XpomAI Посмотреть сообщение
Согласитесь, если процедуру определять таким образом, то функцию можно определить, как процедуру, обязательно возвращающую результат.
Можно.

Это как?
Это, если конструктор находится в ветке if'а или в case, и в одном случае переменная инициализируется одним конструктором, а в др. другим. Именно это и есть полиморфизм.

Есть объекты - забирайте свою инкапсуляцию, а есть структуры/записи - это чистые данные, без дополнительного прицепа
Они уже давно с методами. Тогда в чем отличие от объектов? В том, что наследования нет? Недавно им Init подвезли какой-то. Хотя я уже давно такой метод делал в качестве начальной установки значений структурки.
0
пофигист широкого профиля
4770 / 3207 / 862
Регистрация: 15.07.2013
Сообщений: 18,615
09.09.2023, 01:30
Цитата Сообщение от XpomAI Посмотреть сообщение
Изначально - это где и когда? Помню Init-ы только как конструкторы ещё в паскалевских библиотеках типа TurboVision-а.
Ну да. Там и в те времена они и были.
Цитата Сообщение от XpomAI Посмотреть сообщение
Вообще, пример интересный. Проблемка в том, что хотелось бы увидеть альтернативный способ предварительного выделения под экземпляр класса памяти.
Это к хакерам.
Цитата Сообщение от XpomAI Посмотреть сообщение
Зачем? Опять городить не нужный хлам. Есть объекты - забирайте свою инкапсуляцию, а есть структуры/записи - это чистые данные, без дополнительного прицепа. Оставьте Кесарю кесарево - не изобретайте лишних сущностей.
Поздно. Записи уже давно не чистые данные.
Цитата Сообщение от Constcat Посмотреть сообщение
Т.е., сначала выделяем память через NewInstance, а затем еще раз, но уже из Create?
Нет. Создание нового экземпляра класса с соответствующим выделением памяти выполняется только при вызове конструктора Create от имени класса, но не от имени уже ранее созданного экземпляра класса. В последнем случае магия компилятора не включается и выполняется только то, что вы видите в коде pas-файла.
Тут кто-то говорил что не понимает зачем такое нужно. Объясню не столько необходимость, сколько возможность. В форуме часто появляются вопросы от новичков, например пишущих тесты. Вопросы типа "Тест пройден. Как мне вернуть всё в начальное состояние?". Если всю инициализацию данных выполнять в OnCreate главной формы, то самое то.
0
 Аватар для Beltar
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,662
09.09.2023, 01:44
Вообще-то методы у записей всего-лишь способ сделать нормальным поиск процедурок подходящих для них, т. к. функционально

Delphi
1
2
3
4
5
6
7
8
9
10
11
TMyRec=record
  a,b:Integer;
  procedure Sum:Integer;
end;
 
//И
TMyRec=record
  a,b:Integer;
end;
 
procedure Sum(R:TMyRec):Integer;
Абсолютно одно и то же, но в первом случае мы сразу видим, что такой метод для структурки определен, а во 2-ом нет. Для этой же цели ввели хелперы. Сама запись в виде "дрова.колоть(топором)" более удобна, чем "колоть(топором, дрова)".

Как бы дедуля Вирт не маразматничал в своем маразматичном Обероне по этому поводу.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
09.09.2023, 11:55  [ТС]
Цитата Сообщение от northener Посмотреть сообщение
Создание нового экземпляра класса с соответствующим выделением памяти выполняется только при вызове конструктора Create от имени класса, но не от имени уже ранее созданного экземпляра класса. В последнем случае магия компилятора не включается и выполняется только то, что вы видите в коде pas-файла.
Это вы точно знаете, или предполагаете?
Цитата Сообщение от Beltar Посмотреть сообщение
Это, если конструктор находится в ветке if'а или в case, и в одном случае переменная инициализируется одним конструктором, а в др. другим. Именно это и есть полиморфизм.
Это не полиморфизм. Это раздолбайство. Разумеется, в конструкторе можно совместить различные варианты инициализации объекта. В том же C++ этому (как характерно для C++)))))) целые статьи и теории посвящаются))) В том числе - и статьи, как бороться с геммором, когда конструктор бросает исключение)))

Мой опыт показывает, что конструктор максимум должен инциализировать статические поля объекта. А все остальное лучше вынести в некую процедуру Init, или какой-нибудь Setup, никто не мешает их несколько написать, для различных условий.
Цитата Сообщение от Beltar Посмотреть сообщение
Они уже давно с методами. Тогда в чем отличие от объектов? В том, что наследования нет? Недавно им Init подвезли какой-то.
Не понял. Ты про какие структуры? Из C++? Там это полноценные классы, отличия только в мелочах, типа видимости полей "по-умолчанию".

Добавлено через 11 минут
Цитата Сообщение от Beltar Посмотреть сообщение
Сама запись в виде "дрова.колоть(топором)" более удобна, чем "колоть(топором, дрова)".
Ну, это смотря кому и смотря, в каких ситуациях.
Запись в виде "колоть(чем, что)" более универсальна (например, "колоть(топором, дрова)"/"колоть(шприц, задница)")))
Тем более, что в примере "дрова.колоть()" есть нелогичность в том, что у объекта "дрова" есть метод "колоть". Хотя метод "колоть" присущ, скорее дровосеку. В этом смысле конструкция, которую предложил XpomAI, более логична - "дровосек.колоть(дрова, топор)".
Грубо говоря:
MyVar:=TMyClass.Create - это что-то типа: "Эй, класс! Создай мне объект из самого себя!"
MyVarL:=New(TMyClass,Create) - "Эй, менеджер памяти! Создай мне объект, описанный классом TMyClass, и вызови его конструктор Create"
- последний вариант выглядить гораздо естественней и логичнее.
0
 Аватар для Beltar
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,662
09.09.2023, 13:03
Цитата Сообщение от Constcat Посмотреть сообщение
Это не полиморфизм. Это раздолбайство. Разумеется, в конструкторе можно совместить различные варианты инициализации объекта. В том же C++ этому (как характерно для C++)))))) целые статьи и теории посвящаются))) В том числе - и статьи, как бороться с геммором, когда конструктор бросает исключение)))
По поводу работы конструкторов в Delphi и Си++ была очень давно статья большая на Delphikingdom. Но если вкратце, то в Delphi конструктор ВСЕГДА в try-блоке.

Если я объявил переменную, допустим

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
TVehicleUnit=class(TUnit)
...
end;
 
TFlyingUnt=class(TUnit)
...
end;
 
var Unit:TUnit
begin
if CreateFlyingUnit then Unit:=TFlyingUnit.Create
                           else Unit:=TVehicleUnit.Create
end;
Имею я право так сделать? Имею. Какая ветка будет вызвана в каждом случае неизвестно. В случае дельфового record такое невозможно, т. к. память под Unit будет выделена на стеке при вызове процедурки с этой переменной, в размере, необходимом для этой переменной. С классом просто, есть выделенная память под ссылку, в которую будет засунута ссылка на созданный экземпляр, который знает свой класс. Отсюда и вопрос, если в объектной модели, объекты похожи на структуры, пусть и с наследованием, то как с ними сделать подобное?

Цитата Сообщение от Constcat Посмотреть сообщение
Тем более, что в примере "дрова.колоть()" есть нелогичность в том, что у объекта "дрова" есть метод "колоть". Хотя метод "колоть" присущ, скорее дровосеку.
С точки зрения человеческого языка вы абсолютно правы, особенно, для русского и английского, которые являются SVO-языками (Subject Verb Object), хотя в мире статистически самыми распространенными являются SOV-языки, а SVO только на 2-ом месте. И такая критика ООП тоже есть. Проблема в том, что программист живет в другой реальности, у него, как правило, есть объект, с которым надо что-то сделать. У массива чисел посчитать среднее значение например. Набор данных заполнить. И к этому объекту прилагается набор прописанных методов обработки.

Это из разряда, почему в компьютерной игре персонаж часто не может перелезть через метровый заборчик или залезть куда-то через окно. И человека, который до того с компьютерными играми, да и вообще компьютерам, дела не имел это может вогнать в ступор. Он просто не понимает того, что вроде большой мир игры прописан ограничено, и простые в реальности действия в нем могут быть в силу каких-то причин не прописаны. А с др. стороны геймдизайнеры оказываются в ситуации, что надо как-то объяснить игроку, что какое-то обычно невозможное действие конкретно здесь возможно. И в миллионе игр вертикальные поверхности, по которым можно лезть, окрашиваются какой-то одной текстурой, ящики, которые можно открыть, и платформы, на которые можно запрыгнуть, помечены зелеными маркерами.

И программисту, имея объект дрова, проще нажать точку и получить список того, что можно сделать с дровами. По крайней мере, что создатель дров предусмотрел.

Класс типа Дровосек, в принципе, тоже возможен, например, сюда можно отнести классы соединений с БД. Это хорошо работает, когда есть некоторая большая область, в которой нужно много сервисных действий и централизация. Создавать подключение к БД для каждого набора данных, очевидно, бред, пусть этим один класс занимается.

Цитата Сообщение от Constcat Посмотреть сообщение
MyVar:=TMyClass.Create - это что-то типа: "Эй, класс! Создай мне объект из самого себя!"
Это путаница между классом и экземпляром класса. Есть описание класса, по его образу и подобию создаются экземпляры. Зачем добавлять еще какой-то метод? Даже если он есть где-то в кишках. Только потому что в реальности, имея модель автомобиля надо иметь завод, который по чертежам сделает конкретный экземпляр? Но в программировании все не так. В 90-ые были идеи сделать UI, похожий на офисный стол. Для тех, кто привык. Это не зашло. Терминология от Windows осталась (папка, документ, раб. стол, корзина,...) но не более.
0
 Аватар для Пытливый
3765 / 2272 / 706
Регистрация: 29.05.2013
Сообщений: 9,622
09.09.2023, 13:26
Цитата Сообщение от Beltar Посмотреть сообщение
Это путаница между классом и экземпляром класса. Есть описание класса, по его образу и подобию создаются экземпляры. Зачем добавлять еще какой-то метод?
Это особенность языка программирования, когда с целью компактности кода вы при создании объекта задаете важные параметры его создания. Если бы ЯП не требовал соблюдения синтаксических правил, то и таких вот изысков возможно бы не появилось, хотя классический пример пунктуации: "Казнить нельзя помиловать" говорит, что не все так просто
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
09.09.2023, 14:58  [ТС]
Цитата Сообщение от Beltar Посмотреть сообщение
if CreateFlyingUnit then Unit:=TFlyingUnit.Create
else Unit:=TVehicleUnit.Create
А, я теперь понял, что имелось ввиду. А я подумал, что речь идет о вызовах различных вариантов конструкторов в пределах одного класса.

Цитата Сообщение от Beltar Посмотреть сообщение
Это путаница между классом и экземпляром класса. Есть описание класса, по его образу и подобию создаются экземпляры. Зачем добавлять еще какой-то метод?
Какая путаница? Вот именно, что по описанию класса и создается экземпляр при помощи New. Собственно, в потрохах компилятора так и происходит, о чем в и упомянули:
Цитата Сообщение от Beltar Посмотреть сообщение
Даже если он есть где-то в кишках.
Цитата Сообщение от Beltar Посмотреть сообщение
Только потому что в реальности, имея модель автомобиля надо иметь завод, который по чертежам сделает конкретный экземпляр? Но в программировании все не так.
Так именно такая и была идея, когда внедрялось ООП. Разговор шел не о полиморфизме/инкапсуляции/пр., а именно об объектах (как аналогии с объектами в реальном мире) и о взаимодействии между ними. Взаимодействие между объектами было одной из основных положений ООП, о чем сейчас благополучно забыто с всепоглощающими попытками построить систему "слоев абстракций" и потом различными костылями передавать информацию между этими слоями.

Добавлено через 6 минут
Цитата Сообщение от Beltar Посмотреть сообщение
И программисту, имея объект дрова, проще нажать точку и получить список того, что можно сделать с дровами. По крайней мере, что создатель дров предусмотрел.
Угу. А потом на игровых форумах обсуждения на тему: "Почему танк взорвать можно, а деревянную дверь нельзя". Ну да. Создатель в объекте "дверь" предусмотрел только два метода "открыть/закрыть"))))))))
0
Модератор
4153 / 2362 / 814
Регистрация: 15.11.2015
Сообщений: 9,496
09.09.2023, 16:36
Всё же, аналогия "класс - это чертёж, объект - сама деталь, сделанная по чертежу" слишком абстрактная.
У нас "объект" это просто кусок памяти, ссылка на которую передаётся в соответствующие методы объекта. По факту, методы существуют независимо от объекта, сидят прямо в классе, если хотите, но знают, по какому смещению от конкретного адреса найти нужные поля.
Итак, создание объекта заключается в том, чтобы выделить память под него. Просто сколько нужно выделять памяти знает конструктор самого класса, то есть, записано в скрытом поле. А в случае с записью это значение просто вбито в скомпилированный код в месте вызова GetMem.
0
462 / 185 / 32
Регистрация: 04.08.2018
Сообщений: 732
09.09.2023, 17:06
Цитата Сообщение от Beltar Посмотреть сообщение
1) Процедура это функция, не возвращающая обязательно результата.
Цитата Сообщение от XpomAI Посмотреть сообщение
Согласитесь, если процедуру определять таким образом, то функцию можно определить, как процедуру, обязательно возвращающую результат. Нет?
Оба два нет. Из ваших определений следует, что процедура может возвращать результат. Но и функция тоже может возвращать, а может не возвращать результат. И получается что разницы нет. А она есть.
Давать им определения лучше через забытое понятие подпрограммы. И процедура и функция это подпрограммы. Функция отличается от процедуры тем, что может быть операндом выражения, а процедура - нет.
0
242 / 208 / 36
Регистрация: 19.02.2021
Сообщений: 1,431
09.09.2023, 17:17  [ТС]
Цитата Сообщение от AzAtom Посмотреть сообщение
Итак, создание объекта заключается в том, чтобы выделить память под него. Просто сколько нужно выделять памяти знает конструктор самого класса, то есть, записано в скрытом поле. А в случае с записью это значение просто вбито в скомпилированный код в месте вызова GetMem.
И тоже не так))).
Object'у не требуется конструктор, если отсутствуют виртуальные методы.
По большому счету, конструктор был нужен исключительно ради заполнения таблиц VTM и DMT. Память для объекта выделялась стандартными методами, как и для любой переменной.
Но потом кто-то решил, что экземпляр класса нужно обязательно создавать в куче (что, как по мне - очень странное решение. Даже страннее, чем все классы порождать от TObject) и совместить (теперь уже ставшим обязательным) выделение памяти с конструктором.

Добавлено через 1 минуту
Цитата Сообщение от Rayvenor Посмотреть сообщение
Давать им определения лучше через забытое понятие подпрограммы. И процедура и функция это подпрограммы. Функция отличается от процедуры тем, что может быть операндом выражения, а процедура - нет.
Методы. Мне нравится. Хорошее общее определение)))
0
 Аватар для Beltar
1074 / 514 / 41
Регистрация: 05.05.2022
Сообщений: 3,662
09.09.2023, 17:42
Delphi
1
 хотя классический пример пунктуации: "Казнить нельзя помиловать" говорит, что не все так просто
Меня до сих пор трясет от того, что происходит в програмке на Си, если пропустить амперсанд в каком-нибудь printf.

Цитата Сообщение от Constcat Посмотреть сообщение
Вот именно, что по описанию класса и создается экземпляр при помощи New
Представим, что класс уже имеет завод по выпуску объектов.

Цитата Сообщение от Constcat Посмотреть сообщение
Так именно такая и была идея, когда внедрялось ООП. Разговор шел не о полиморфизме/инкапсуляции/пр., а именно об объектах (как аналогии с объектами в реальном мире) и о взаимодействии между ними. Взаимодействие между объектами было одной из основных положений ООП, о чем сейчас благополучно забыто с всепоглощающими попытками построить систему "слоев абстракций" и потом различными костылями передавать информацию между этими слоями.
Программа состоит не из объектов, а из алгоритмов. ООП же часть обобщенного программирования, когда предполагается, что разные, но похожие объекты должны обрабатываться одинаково.

Цитата Сообщение от Rayvenor Посмотреть сообщение
Оба два нет. Из ваших определений следует, что процедура может возвращать результат. Но и функция тоже может возвращать, а может не возвращать результат. И получается что разницы нет. А она есть.
Давать им определения лучше через забытое понятие подпрограммы. И процедура и функция это подпрограммы. Функция отличается от процедуры тем, что может быть операндом выражения, а процедура - нет.
Функция, не возвращающая значение в Си все равно называется функцией. Понятно, что термин этот пришел из математики, хотя в чисто математическом смысле функция в программировании должна быть чистой, т. е. не вносить никаких изменений вне себя, кроме возврата результата. procedure же - чисто паскалевский термин. Может алголовский, но мне лень проверять.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
09.09.2023, 17:42

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() ...


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Запрет дублирования строк в табличной части
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) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru