Форум: "Прочее";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];
ВнизВстречаем Record Helper Найти похожие ветки
← →
oxffff © (2007-03-12 01:07) [40]
> Юрий Зотов © (12.03.07 01:00) [38]
> > oxffff © (12.03.07 00:52) [35]
>
> Тоже не понял.
type
identifierName = class helper [(ancestor list)] for classTypeIdentifierName
memberList
end;
← →
oxffff © (2007-03-12 01:10) [41]Вообщем не смешаете вы таким образом Stack и Ref семантику
← →
jack128 © (2007-03-12 01:16) [42]oxffff © (12.03.07 0:52) [35]
Ancestor list - это опечатка.
Или баг в реализации компилира ;-)
Хотя по зрелому размышлению я таки пришел к выводу, что тут нужно думать, стоит ли такую фишку делать. Нужно смотреть, как, например, в С++ решаются конфликты имен при множественном наследовании..
oxffff © (12.03.07 0:26) [22]
Зачем так усложнять. Перегружаешь NewInstance и FreeInstance.
В куче выделяешь псевдо стек. И свой esp в переменной.
Не. Тогда те придется самому вызывать деструктор. А это - лень. Хочется, чтоб все само вызывалость :-) Как с С++
Юрий Зотов © (12.03.07 0:22) [21]
var
MyClass: TMyClass; static;
А если у клааса перекрыт NewInstance - что делать? Вс равно в стеке выделять память? А не порушится ничего из-за этого?
oxffff © (12.03.07 1:10) [41]
Вообщем не смешаете вы таким образом Stack и Ref семантику
+1 :-)
← →
euru © (2007-03-12 01:19) [43]Я до сих пор не могу понять, какие проблемы может вызвать наличие у рекорда возможностей наследования и виртуальных функций?
← →
oxffff © (2007-03-12 01:21) [44]
> jack128 © (12.03.07 01:16) [42]
> oxffff © (12.03.07 0:52) [35]
> Ancestor list - это опечатка.
> Или баг в реализации компилира ;-)
> С++ решаются конфликты имен при множественном наследовании
Нет пусть будет одиночное наследование, abstract base class пусть останется С++.
:)
← →
Юрий Зотов © (2007-03-12 01:22) [45]> oxffff © (12.03.07 01:03) [39]
> Конструктор вызывает classCreate
Нет. Сам по себе - не вызывает. Код вызова classCreate вставляет компилятор в пролог конструктора, если тот был вызван, как классовый метод (и не вставляет, если как обычный).
> у конструктора должна быть информация выделять память или нет
Зачем? Пусть все остается, как есть. Просто компилятор при входе в область видимости static-переменной сам вызовет конструктор, как классовый метод - и память будет выделена. Соответственно при выходе их этой области компилятор сам вставит вызов Free - и память будет освобождена.
Впрочем, есть и совсем простой вариант - сразу выделить память под static-объект не в хипе, а в основной области.
> Static "переменной вы ничего не присвоите
Само собой. Но почему бы компилятору это не контролировать? Он же контролирует присвоение констант, а это то же самое.
← →
oxffff © (2007-03-12 01:24) [46]
> Я до сих пор не могу понять, какие проблемы может вызвать
> наличие у рекорда возможностей наследования и виртуальных
> функций?
Достоинство record в его light in weight.
Конструктору по умолчанию и отсутствии деструктора.
← →
oxffff © (2007-03-12 01:31) [47]
> Нет. Сам по себе - не вызывает. Код вызова classCreate вставляет
> компилятор в пролог конструктора, если тот был вызван, как
> классовый метод (и не вставляет, если как обычный).
dl влияет на вызов ClassCreate и на AfterConstruction.
> > у конструктора должна быть информация выделять память
> или нет
>
> Зачем? Пусть все остается, как есть. Просто компилятор при
> входе в область видимости static-переменной сам вызовет
> конструктор, как классовый метод - и память будет выделена.
> Соответственно при выходе их этой области компилятор сам
> вставит вызов Free - и память будет освобождена.
Какой конструктор? По умолчанию? Удобно? Нет.
>Впрочем, есть и совсем простой вариант - сразу выделить память под >static-объект не в хипе, а в основной области.
Если переменная глобальна, то просто.
А если локальна, как определить достижимость метода в котором объявлена.
Скажите если ли в этом смысл.
← →
GrayFace © (2007-03-12 01:34) [48]oxffff © (12.03.07 0:26) [22]
Зачем так усложнять. Перегружаешь NewInstance и FreeInstance.
В куче выделяешь псевдо стек. И свой esp в переменной.
Зачем так усложнять?type
TMyObj = class(TObject)
protected
class function NewInstance: TObject; override;
procedure FreeInstance; override;
public
constructor Create(Address:Pointer);
end;
constructor TMyObj.Create(Address: Pointer);
begin
end;
procedure TMyObj.FreeInstance;
begin
CleanupInstance;
end;
class function TMyObj.NewInstance: TObject;
asm
mov edx, ecx
call InitInstance
end;
Только при наследовании от такого класса надо сохранять Address первым аргументом.
← →
oxffff © (2007-03-12 01:35) [49]
> > Static "переменной вы ничего не присвоите
Более того ее саму будет опасность присваивать.
Потому, что приемник не будет знать как она выделена.
Да и семаника будет Ref и value.
← →
oxffff © (2007-03-12 01:38) [50]
> GrayFace © (12.03.07 01:34) [48]
> oxffff © (12.03.07 0:26) [22]
> Зачем так усложнять. Перегружаешь NewInstance и FreeInstance.
>
> В куче выделяешь псевдо стек. И свой esp в переменной.
> Зачем так усложнять?
> type
> TMyObj = class(TObject)
> protected
> class function NewInstance: TObject; override;
> procedure FreeInstance; override;
> public
> constructor Create(Address:Pointer);
> end;
>
> constructor TMyObj.Create(Address: Pointer);
> begin
> end;
>
> procedure TMyObj.FreeInstance;
> begin
> CleanupInstance;
> end;
>
> class function TMyObj.NewInstance: TObject;
> asm
> mov edx, ecx
> call InitInstance
> end;
> Только при наследовании от такого класса надо сохранять
> Address первым аргументом.
Ну. Ну.
Только не забудьте в конструктор передать адресс экземпляра.
← →
jack128 © (2007-03-12 01:38) [51]oxffff © (12.03.07 1:24) [46]
отсутствии деструктора.
есть. И конструкторы и деструкторы. Называются _InitializeRecord и _FinalizeRecord соответственно. Говорят в qc просят возможность их переопределить
← →
jack128 © (2007-03-12 01:40) [52]jack128 © (12.03.07 1:38) [51]
Говорят, в qc просят дать возможность их переопределять
← →
oxffff © (2007-03-12 01:40) [53]
> > constructor Create(Address:Pointer);
Не заметил.
Ну наверно с псевдостеком и псевдо esp. Будет проще и выразительней.
← →
oxffff © (2007-03-12 01:45) [54]
> _InitializeRecord и _FinalizeRecord соответственно
Это очень полезные compiler magic функции и не только для record. и для класса(TObject.CleanupInstance) и для всех локальных переменных Посмотрите еще есть _FinalizeArray
Соотвественно о деструкторе в record
Records are constructed automatically, using a default no-argument constructor, but classes must be explicitly constructed. Because records have a default no-argument constructor, any user-defined record constructor must have one or more parameters.
Record types cannot have destructors.
← →
GrayFace © (2007-03-12 01:52) [55]euru © (12.03.07 1:19) [43]
Я до сих пор не могу понять, какие проблемы может вызвать наличие у рекорда возможностей наследования и виртуальных функций?
Под виртуальные функции надо VMT инициализировать, хотя переменнные с счетчиками ссылок инициализируются нулями и ничего. Наследование - сам не понимаю, почему его в C# запретили.
oxffff © (12.03.07 1:40) [53]
Ну наверно с псевдостеком и псевдо esp. Будет проще и выразительней.
Псевдостек - это что? Это чем-то отличается от кучи?
← →
oxffff © (2007-03-12 01:55) [56]
> Псевдостек - это что? Это чем-то отличается от кучи?
Аналог работы с регистром ESP. Только память уже выделана.
Что быстрее Getmem(a,100) или sub esp,100? :)
← →
oxffff © (2007-03-12 01:56) [57]Пора спать. Всем спокойной ночи.
← →
euru © (2007-03-12 02:02) [58]
> oxffff © (12.03.07 01:24) [46]
> Достоинство record в его light in weight. Конструктору по
> умолчанию и отсутствии деструктора.
Так у object всё это было.
← →
euru © (2007-03-12 02:06) [59]
> GrayFace © (12.03.07 01:52) [55]
> Под виртуальные функции надо VMT инициализировать, хотя
> переменнные с счетчиками ссылок инициализируются нулями
> и ничего.
Но ведь работало же это всё с типами object в TurboPascal, начиная с версии 5.5. Мне что-то нигде не встречалась информация о концептуальной неправильности такого подхода.
← →
GrayFace © (2007-03-12 02:29) [60]oxffff © (12.03.07 1:55) [56]
Аналог работы с регистром ESP.
Как ты себе это представляешь? Если бы это было так просто, GetMem работал бы именно так.
euru © (12.03.07 2:06) [59]
Но ведь работало же это всё с типами object в TurboPascal, начиная с версии 5.5. Мне что-то нигде не встречалась информация о концептуальной неправильности такого подхода.
Да я тоже в этом ничего страшного не вижу.
Юрий Зотов © (12.03.07 0:22) [21]
var
MyClass: TMyClass; static;
Плохо то, что первые 4 байта всегда будут забиты. Деструктор всегда есть, значит при объявлении такого объекта в локальной переменной компилятор обязан будет создать try..finally с вызовом деструктора, который, может быть, совсем не нужен.
← →
jack128 © (2007-03-12 10:19) [61]GrayFace © (12.03.07 2:29) [60]
который, может быть, совсем не нужен.
всегда нужен. Еще раз, деструкторы вызваются для всех записей, и в этом смысле классы ничем не отличаются от записей. Единственная разница, что у классов деструктор должен быть виртуальный, а у записей - он статический.
← →
oxffff © (2007-03-12 10:22) [62]
> Как ты себе это представляешь? Если бы это было так просто,
> GetMem работал бы именно так.
Представляю себе нормально.
Посмотри как выделяется память для локальных переменных.
Реализуй тот же подход, используя предвыделенный объект памяти в куче.
← →
oxffff © (2007-03-12 10:23) [63]
> Еще раз, деструкторы вызваются для всех записей, и в этом
> смысле классы ничем не отличаются от записей
В классическом понимании нет.
oxffff © (12.03.07 01:45) [54]
← →
jack128 © (2007-03-12 10:26) [64]oxffff © (12.03.07 10:23) [63]
В классическом понимании нет.
ой, да ладно. Для освобождения ресурсов связанных с записями и объектами вызвается некий код. Как он называется - дело десятое, в общем то...
← →
oxffff © (2007-03-12 10:28) [65]У записи нет деструктора. Компилятор финализирует записи, объекты, набор переменных для типов.
tkVariant
tkArray:
tkRecord:
tkInterface:
tkDynArray:
Смотри здесь ничего нет про классы.
← →
Игорь Шевченко © (2007-03-12 10:30) [66]Юрий Зотов © (12.03.07 00:50) [34]
SaveToFile документирован разрабтчиком класса TMemoStrings, вообще-то. Если не трудно, почитай соседнюю ветку, чтобы мне два раза не писать одно и то же
← →
oxffff © (2007-03-12 10:31) [67]
> ой, да ладно.
Это не декструтор.
Посмотри _FinalizeArray вызывается и для объектов, набора переменных, записи. Это универсальный псевдо-деструктор, который освобождает ресурсы встроенных типов.
← →
oxffff © (2007-03-12 10:35) [68]
> oxffff © (12.03.07 10:22) [62]
>
> > Как ты себе это представляешь? Если бы это было так просто,
>
> > GetMem работал бы именно так.
>
> Представляю себе нормально.
> Посмотри как выделяется память для локальных переменных.
>
> Реализуй тот же подход, используя предвыделенный объект
> памяти в куче.
предвыделенный объект = кусок памяти >1МВ
← →
REA (2007-03-12 10:46) [69]Тогда давайте сделаем вcе классами:
s := (x.sin * y.cos).ToStr;
И class helper-ы еще чтобы дописывать чужие классы без наследования.
← →
euru © (2007-03-12 11:28) [70]
> REA (12.03.07 10:46) [69]
А что в этом выражении крамольного? (То, что это не будет работать в текущих версиях Delphi, я знаю.)
← →
oxffff © (2007-03-12 12:06) [71]
> euru © (12.03.07 11:28) [70]
>
> > REA (12.03.07 10:46) [69]
> А что в этом выражении крамольного? (То, что это не будет
> работать в текущих версиях Delphi, я знаю.)
Торопитесь.
SingleWrapper=packed record
value:Single;
function Sin:SingleWrapper;
function Cos:SingleWrapper;
function ToStr:string;
constructor create(Value:single);
class operator Multiply(a,b:SingleWrapper):SingleWrapper;
end;
{ SingleWrapper }
function SingleWrapper.Cos: SingleWrapper;
begin
Result.value:=System.cos(value);
end;
constructor SingleWrapper.create(Value: single);
begin
self.value:=Value;
end;
class operator SingleWrapper.Multiply(a, b: SingleWrapper): SingleWrapper;
begin
Result.value:=a.value*b.value;
end;
function SingleWrapper.Sin: SingleWrapper;
begin
Result.value:=System.sin(value);
end;
function SingleWrapper.ToStr: string;
begin
result:=FloatToStr(value);
end;
procedure TForm1.Button1Click(Sender: TObject);
var x,y:SingleWrapper;
s:string;
begin
x.create(1);
y.create(2);
s:=(x.Sin*y.Cos).ToStr;
showmessage(s);
end;
← →
Юрий Зотов © (2007-03-12 12:07) [72]> Игорь Шевченко © (12.03.07 10:30) [66]
Игорь, я читал. Согласен с мнением, что, уж если я использую чью-либо библиотеку/модуль, то, соответственно, должен ее освоить. То есть, разработчик должен ее каким-то образом документировать, а я должен эту документацию изучить. Чтобы и использовать ее грамотно, и не падать в обморок от Memo.Lines.DoWork.
Собственно, то же самое относится и к VCL.
← →
euru © (2007-03-12 12:23) [73]
> oxffff © (12.03.07 12:06) [71]
:) Точно. Поторопился. Но меня больше интересовал вопрос, что крамольного, если такую возможность будет поддерживать компилятор.
Что-то типаvar
x, y: Double;
s: String;
begin
s := (sin(x) * cos(y)).ToString;
end;
← →
Аноним (2007-03-12 12:27) [74]Memo1.Lines.AddFmt("Позиция номер %d", [i]);
Вариантов избежать обморока совсем никаких?
← →
Игорь Шевченко © (2007-03-12 12:32) [75]Юрий Зотов © (12.03.07 12:07) [72]
> Собственно, то же самое относится и к VCL.
Только что к VCL уже все написано, и ожидаешь от встреченных в коде мест использования VCL штатного и описанного поведения. А то десять разработчиков напишут двадцать хелперов, половина из них в школе албанский изучало вместо английского, и будут методы Memo.Lines.DelayWork
Нафиг такое счастье
← →
Юрий Зотов © (2007-03-12 13:01) [76]> Игорь Шевченко © (12.03.07 12:32) [75]
1. Игорь, ты используешь хоть какие-нибудь сторонние библиотеки?
Вероятно, да. Потому что нет никакого смысла все писать самому. Нерентабельно это.
2. Ты доверяешь тем библиотекам, которые используешь?
Вероятно, тоже да. Иначе бы не использовал.
3. Ты знакомишься с документацией (хелпами, исходниками и т.д.) к этим библиотекам?
Вероятно, тоже да. Иначе не смог бы их использовать.
4. Ты не удивляешься тому, что в какой-то библиотеке некий класс наследуется от стандартного, но при этом модифицирует или расширяет поведение предка?
Вероятно, не удивляешься. Потому что это совершенно нормально - на то оно и ООП. Именно полиморфизм и дает возможность реализовать тот функционал, ради которого, собственно, ты и юзаешь данную библиотеку
5. Ты смотришь в документации (хелпах, исходниках и т.д.), что именно, как именно и для чего именно этот класс-наследник модифицирует/расширяет?
Вероятно смотришь. Чтобы использовать осмысленно и грамотно.
6. Ты НЕ используешь библиотеки, которым НЕ доверяешь?
Вероятно, нет. Потому что это опасно. Глюков хватает и без того.
===============================
Теперь совершенно стандартная ситуация: ты нуждаешься в некоем функционале. Ты нашел библиотеку, которая его реализует. Ты посмотрел ее код, ее документацию и увидел, что все это написано грамотно (или неграмотно) и доверять авторам можно (или нельзя). Цена библиотеки и качество ее поддержки тебя тоже вполне устраивают (или не устраивают). И в итоге ты принял решение, что будешь (или не будешь) ее использовать.
Теперь скажи - что меняется от того, есть ли в этой библиотеке хелперы, или их нет?
Ни-че-го. Спор, извини, ни о чем.
А албанский имеет отношение к ламерам, а не к хелперам. Между собой же эти два понятия НИКАК не связаны. Не передергивай, пожалуйста.
← →
Игорь Шевченко © (2007-03-12 13:08) [77]Юрий Зотов © (12.03.07 13:01) [76]
Я вижу, что пишут люди. Так вот сложилось. Я вижу, к каким результатам приводит использование средств, потенциально позволяющих делать код более непонятным.
> А албанский имеет отношение к ламерам, а не к хелперам.
> Между собой же эти два понятия НИКАК не связаны. Не передергивай,
> пожалуйста.
А я не передергиваю. Какой человеческий материал имеется, с тем и приходится работать.
← →
Юрий Зотов © (2007-03-12 13:25) [78]> Игорь Шевченко © (12.03.07 13:08) [77]
> Я вижу, что пишут люди.
Очевидно, люди бывают разные.
> Я вижу, к каким результатам приводит использование средств,
> потенциально позволяющих делать код более непонятным.
Очевидно, потенциальная возможность еще не означает, что она непременно будет реализована. Смотря, кто и как пишет код. Синтаксис Си тоже позволяет сломать глаза на первой же строчке, но люди грамотные и на Си пишут вполне понятно.
> А я не передергиваю. Какой человеческий материал имеется, с тем и
> приходится работать.
Очевидно, хелперы тут все же ни при чем. Ну не виноваты они в твоем человеческом материале, чего ты на них так взъелся?
Тогда уж и полиморфизм - тоже долой. Потому что человеческий материал ведь и метод заместить запросто может - тоже потенциальная опасность. Да и вообще - долой программирование. Потому что человеческий материал может влепить баг вообще в любом месте кода. Даже и не в объекте.
==========================
Игорь, я не понимаю. Есть некий механизм, удобный и расширяющий наши возможности. А ты говоришь - долой этот механизм, потому что его могут юзать ламеры, а это опасно.
Тогда долой ружья, автомобили, электричество - и вообще все, вплоть до столовых вилок. Потому что все это тоже могут юзать ламеры, а это опасно.
Странно как-то.
Ты извини, но спор я прекращаю. Просто не вижу предмета.
← →
vuk © (2007-03-12 13:40) [79]Я, кстати, здесь с Юрием согласен. Если средство позволяет решать некоторые задачи более эффективно, то оно имеет право на существование. А вот уж как именно им пользоваться и пользоваться ли вообще, это зависит от понимания возможностей, альтернативных решений и их плюсов с минусами. А запутанный код можно и без всяких хелперов наваять.
← →
Игорь Шевченко © (2007-03-12 13:43) [80]Юрий Зотов © (12.03.07 13:25) [78]
> Игорь, я не понимаю. Есть некий механизм, удобный и расширяющий
> наши возможности. А ты говоришь - долой этот механизм, потому
> что его могут юзать ламеры, а это опасно.
Ну не вижу я удобства. Неудобство вижу - код становится более неочевидным, пример неочевидного кода показал Jack128
Сами Борланды пишут, что не следует использовать это средство для дизайна.
Страницы: 1 2 3 вся ветка
Форум: "Прочее";
Текущий архив: 2007.04.08;
Скачать: [xml.tar.bz2];
Память: 0.65 MB
Время: 0.047 c