-
> Mystic © (15.01.09 13:54) [57]
Я понимаю твою точку зрения, но она напрямую противоречит уже заложенной в Дельфи философии на явность всех декларций. Overload, override, reintroduce и т.п. Т.е. программист явно говорит, что он тут хочет сказать, что бы не вышло случайной перегрузки или переопределения. То, что ты предлагаешь идёт вразрез с этой философией, по-этому я считаю это недосмотром с точки зрения разработчиков языка. Предлагаемый тобой подход в бОльшей степени подошёл бы C++, где компилятор без лишних деклараций делает выводы о перегрузке/переопределении.
Собственно говоря, всё это лишний раз подтверждает, что дисциплина поддержания идеологической целостности и чистоты в Дельфи хромает.
-
> tesseract © (15.01.09 13:57) [59] > > wtih TMySuperPuperClass.Create(TFooChild) do > Прямо вот тут абсолютное приведение с моторчиком.
Здрасьте, приехали. Вчитайтесь в код внимательнее. Просто параметр передается в конструктор, никакого приведения нет.
-
Игорь Шевченко © (15.01.09 12:57) [42]
> Мне было бы крайне любопытно узнать, как при компиляции > данного кода проверить, является ли инстанцируемый класс > абстрактным или содержит непереопределенные абстрактные > методы >
Гороздо любопытнее то, как удалось так скомпилить bpl, так что в него не попало определение одного из базовых классов, или почему это позволил сделать компилятор. Вот это уж точно здравому смыслу противоречит. Скажите, уважаемый а что будет если я изменю код предка до неузнаваемости т.е.: в bpl находится класс T2, который наследуется от T1, я беру и уродую T1, сохраняя название класса, после чего компилирую(?!) и запускаю? А такая ситуация не редкость при переработке проекта, ногда базовые классы менять таки приходится.
Ega23 © (15.01.09 12:55) [41] Приведённый код ничего не показывает. T = class of TMyAbstractClass; T должно содержать признак абстрактности класса
-
> Прямо вот тут абсолютное приведение с моторчиком.
Макс, ты чё? Ты код мой внимательно посмотри.
-
> Приведённый код ничего не показывает. T = class of TMyAbstractClass;
И что? Я передаю в конструктор класс со всеми перекрытыми абстрактными методами.
-
> Макс, ты чё? Ты код мой внимательно посмотри.
with попутал. Обычно так и приводиться к знаменателю у меня 38 если что :-)
-
> у меня 38 если что :-)
сантиметров? Ходить не мешает? :))))))))))))
-
> XentaAbsenta © (15.01.09 12:44) [39]
> Если в классе присутствуют абстрактные методы, то инстанцировать > класс нельзя, потому, что это ведёт к неминуемым ошибкам
Почему неминуемым? Если абстрактный метод реально нигде не вызывается, то и ошибок не будет.
> компилятор должен в таких случаях требовать от программиста посавить > модификатор abstact в определении класса и ни при каких > обстоятельствах не позволять инстанцировать класс
В силу предыдущего, компилятор должен выдать предупреждение (что он и делает), но не делать никаких запретов. Программист это предупреждение получает, но решает сам. Ему виднее, что и как он использует.
> даже через ссылку на класс, которая вполне может тоже может нести в > себе аттрибуты класса.
Игорь уже привел пример, когда на этапе компиляции определить реальный класс невозможно.
> А ошибки времени выполнения отлавливать и исправлять куда сложнее > нежели ошибки компиляции.
Вот с этим никто не спорит. Но если Вы включите показ варнингов и приучите себя программировать так, чтобы не было не только ошибок, но и даже хинтов (то есть, чтобы окошко сообщений компилятора всегда оставалось пустым), то как раз на этапе компиляции все плюшки и выловите.
-
> напрямую противоречит уже заложенной в Дельфи философии > на явность всех декларций. Overload, override, reintroduce > и т.п.
А почему ты ничего не говоришь о safecall, inline? Одни модификаторы для явных деклараций, другие заставляют компилятор выполнять некоторые дополнительные действия... И я бы не говорил о какой-то идеологической целостности Delphi. Идеологическая целостность может быть у С++, где есть специальный комитет, который рассматривает предложения и говорит: эту фичу мы вносить не будем, потому что она противоречит идеологической целостности. Delphi, как мне кажется, больше формировался под влиянием практических потребностей. Насколько я помню, абстрактные методы были введены еще в Turbo Pascal. В те времена больше стояла проблема производительности, поэтому мне представляется вполне логичным, что создание объекта не перегружается дополнительными операциями. Delphi 1 изначально был под Win16, проблема производительности и там сохранялась. Более того, даже стала более актуальной ввиду того, что даже небольшие классы стали создаваться в куче. С другой стороны сами абстрактные методы достаточно редко используются в той же самой VCL. Вот и все :)
-
> Юрий Зотов © (15.01.09 14:32) [67] > Почему неминуемым? Если абстрактный метод реально нигде > не вызывается, то и ошибок не будет.
Есть хорошее эвристическое правило - то, что можно сделать, будет сделано рано или поздно. То этот метод нельзя вызывать либо сам забудешь, либо коллега забудет, либо новенький какой-нибудь сотрудник даже знать не будет.
-
> Ega23 © (15.01.09 13:54) [58]
А я не знаю, о каком AS вы говорите, в [41] нет ни оператора AS , ни свойства AS , ни приведения.
Я отвею на вопрос, чем AS безопаснее.
-
> Я отвею на вопрос, чем AS безопаснее.
Не, я знаю что такое as. Что сначала проверка на is, а потом уже typecast. Я Макса не понял.
-
> Alkid © (15.01.09 14:38) [69]
Ой, в реальном приложении таких мест столько... И абстрактные методы занимают столь малую часть от их числа...
-
2 Ega23 © (15.01.09 13:45) [54]
>> причём я точно знаю, что Write никогда не будет использоваться. >ага, а также WriteBuffer и CopyFrom? ну естественно
-
Григорьев Антон © (15.01.09 10:11) [24]
> Это связано с наличием в Delphi метаклассов и виртуальных > конструкторов. Из-за этого не всегда на этапе компиляции > можно решить, конструктор какого именно класса вызывается > - с абстрактными методами, или его потомка, в котором они > перекрыты. А раз 100%-ый отлов всё равно невозможен, разработчики > Delphi решили не париться с этим вообще и отлавливать всё > только в run-time.
T0 : abstract class T1 : abstract class T2 : class ---------- T0 содержит виртуальный конструктор Create(var tt : anytype), T1 тоже содержит, а T2 не содержит. В этом случае возможно инстанцирование T1, что недопустимо (напр. через ссылку на класс). Выходом может быть ошибка компиляции класса T2 c требованием переопределить к виртуальный конструктор Create(var tt : anytype). Что в купе с прямым запретом к инстанцированию абстрактных классов, приведёт к принципиальной невозможности их инстанцирования.
------------------ насчёт идеалогии - на кой ляд тогда нужно слово абстракт, для красоты?
-
> Ega23 (15.01.2009 14:47:11) [71]
А я подумал, что ко мне претензии.
-
> насчёт идеалогии - на кой ляд тогда нужно слово абстракт, > для красоты?
О! Это уже другой вопрос. Поройся в архиве, я весной эту тему поднимал. Достаточно жаркая дискуссия была. Как в виртуале, так и потом в реале.
-
74 а это уже приведёт к принципиальной невозможности получить EAbstractError
-
> Alkid © (15.01.09 14:38) [69]
Благодарю за пояснение, но оно лишнее - я достаточно давно работаю в командах, так что это (и не только это) эвристическое правило знаю даже слишком хорошо (увы).
Но как раз на такой случай варнинги и существуют. И этого достаточно.
-
> XentaAbsenta © (15.01.09 14:51) [74]
> В этом случае возможно инстанцирование T1, что недопустимо (напр. > через ссылку на класс). Выходом может быть ошибка компиляции класса > T2 c требованием переопределить к виртуальный конструктор Create > Что в купе с прямым запретом к инстанцированию абстрактных классов, > приведёт к принципиальной невозможности их инстанцирования.
Даже если в T2 перекрыть конструктор, создать экземпляр T1 через ссылку на класс все равно будет можно. И на этапе компиляции будет невозможно отследить, экземпляр какого именно класса создается.
> на кой ляд тогда нужно слово абстракт, для красоты?
На тот ляд оно нужно, чтобы в НЕабстрактных методах абстрактного класса было можно вызывать его же абстрактные методы.
TFigure = class private FSize: ... procedure SetSize(...); public procedure Draw; virtual; abstract; property Size: ... read FSize write SetSize; end;
TCircle = class(TFigure) public procedure Draw; override; end;
procedure TFigure.SetSize(...); begin ... Draw; // Вот зачем нужен абстрактный метод end;
procedure TCircle.Draw; begin ... // реальная отрисовка end;
|