MrShoor
> Чем не синглтон?
для паскаля слишком много повторяющихяя буков "class var" xD
в бытность Delphi 7 решали так:
interface type IMySingle = interface function Foo(): Boolean; procedure Bar( ); end; var MySingle : IMySingle; implementation type TMySingle = class( IMySingle) ... initialization MySingle := TMySingle.Create;
той же class var в Delphi 7 не было. (property к interface-ам, к сожалению завезли позже)
Ну или глобальные переменные (запрятанные в implementation) с публичными функциями и процедурами
но основная крутизна подхода - использование паскалевских модулей.
skalogryz
> либо прописывать инициализацию руками
Тут сложно сказать. С одной стороны жизнь до main - это непредсказуемые грабли (даже в делфи, где порядок инициализации модулей разруливается). С другой стороны, если данные простые, то оно действительно облегчает жизнь.
Вот что на С# боль - так это то, что там мало того, что нет forward declaration, так еще и C# забивает болт на порядок инициализации static классов, превращая жизнь до main в настоящее минное поле. А вообще поработав с C# у меня только разочарования возникли. А от некоторых "решений" языка аж пригорает. Причем разработчики только C# не видят в этом никакой проблемы.
MrShoor
А как ты себе представляешь задание порядка инициализации статиков? Явным атрибутом с группами аля:
[StaticInitializer(InitializerOrder.Render)] static class A { }
?
А вообще static конструктор как и инициализация вызываются при первом использовании же, а не до main
MDXEv2
> А как ты себе представляешь задание порядка инициализации статиков?
Ну в C# сейчас никак, т.к. нет явных зависимостей.
> А вообще static конструктор как и инициализация вызываются при первом
> использовании же, а не до main
И тем не менее это не мешает наступить себе же на хвост:
https://weblog.west-wind.com/posts/2020/May/04/Static-Constructor… -Order-Errors
Залез в System.pas и там обнаружил вот такое:
{ Virtual method table entries } vmtSelfPtr = -76; vmtIntfTable = -72; vmtAutoTable = -68; vmtInitTable = -64; vmtTypeInfo = -60; vmtFieldTable = -56; vmtMethodTable = -52; vmtDynamicTable = -48; vmtClassName = -44; vmtInstanceSize = -40; vmtParent = -36; vmtSafeCallException = -32 deprecated; // don't use these constants. vmtAfterConstruction = -28 deprecated; // use VMTOFFSET in asm code instead vmtBeforeDestruction = -24 deprecated; vmtDispatch = -20 deprecated; vmtDefaultHandler = -16 deprecated; vmtNewInstance = -12 deprecated; vmtFreeInstance = -8 deprecated; vmtDestroy = -4 deprecated; vmtQueryInterface = 0 deprecated; vmtAddRef = 4 deprecated; vmtRelease = 8 deprecated; vmtCreateObject = 12 deprecated;
Это к каждому объекту добавляется минимум 80 байт мета-информации?
g-cont
Ну да. Что не так?
MDXEv2
Многовато как-то будет, не?
И вот еще такой вопрос:
TComponent = class(TPersistent, IInterface, IInterfaceComponentReference)
Это множественное наследование или что-то иное?
g-cont
> Это к каждому объекту добавляется минимум 80 байт мета-информации?
К каждому классу, а не объекту.
function TObject.ClassType: TClass; begin Pointer(Result) := PPointer( Self)^; end; procedure TObject.CleanupInstance; {$IFDEF PUREPASCAL} var ClassPtr: TClass; InitTable: Pointer; begin {$IFDEF WEAKREF} _CleanupInstance( Self); {$ENDIF WEAKREF} ClassPtr := ClassType; repeat InitTable := PPointer( PByte( ClassPtr) + vmtInitTable)^; if InitTable <> nil then _FinalizeRecord( Self, InitTable); ClassPtr := ClassPtr.ClassParent; until ClassPtr = nil; TMonitor.Destroy( Self); end; {$ELSE !PUREPASCAL} ...
Т.е. ссылка на объект типа TObject как указатель ссылается на его первый байт в памяти где сразу же хранится указатель на таблицу виртуальных методов.
Одновременно с этим же эта таблица виртуальных методов является объектом класса - наследник от TClass.
class function TObject.InstanceSize: Integer; begin Result := PInteger(PByte( Self) + vmtInstanceSize)^; end;
В последнем случае Self это не TObject, а TClass (class function).
g-cont
> Это множественное наследование или что-то иное?
Это интерфейсы. Пришли в Delphi для нативной поддержки COM-объектов Microsoft и только от интерфейсов можно наследоваться более одного раза.
В целом лучше не забивать ими себе голову. Тема довольно большая и глубокая, но VCL старается их не использовать если речь не идёт про взаимодействия с COM-объектами.
g-cont
> Залез в System.pas и там обнаружил вот такое:
ты кончишь тем, что тебе будет проще делфи код поддерживать, чем писать конвераторы и мучаться с крестами.
=A=L=X=
> В целом лучше не забивать ими себе голову
автору конвертера, нельзя не забивать, потому что базовый TComponent уже реализует два интерфейса.
Если забить, то в итоге уже будет скорее транслятор, чем конвертатор.
(в данном случае "транслятор" подразумевается как "убогий недоконвертатор" xD)
ЗЫ: если учесть что Interface-ы были вещью модной в Делфи среде, то их использование можно встретить в сторонних библиотеках.
skalogryz
> Если забить, то в итоге уже будет скорее транслятор, чем конвертатор.
Я думаю это автору и надо. Не "поддерживать все сторонние библиотеки компонентов", а "один раз сконвертить VCL чтобы в своей среде получить удобные формочки."
>>и только от интерфейсов можно наследоваться более одного раза
Понял.
>>ты кончишь тем, что тебе будет проще делфи код поддерживать
Я просто пытаюсь определить что мне понадобится.
>>чем писать конвераторы и мучаться с крестами
То что выдаст конвертор не будет компилироваться. Это для более удобного чтения исходников.
g-cont
> То что выдаст конвертор не будет компилироваться.
то что не будет даже компилироваться, зачастую просто пустая трата времени. Хотя бы потому, что ты не сможешь проверить, правильно сконвертировалось или нет.
>>Хотя бы потому, что ты не сможешь проверить, правильно сконвертировалось или нет.
Я в спорных местах оставляю коммент на верификацию.
А вот эта конструкция что обозначает?
foo = 1..256;
Переменная, значения которой будут удерживаться в указанных рамках?
g-cont
Тип, а не переменная. Переменная выглядит так
x: 1..256
И "удерживаться" громко сказано, просто при присвоении будут проверки, если включен {$RANGECHECKS ON}
Если ты её, скажем, не инициализируешь, то там и какой-нить 38645 может оказаться.