
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.30] |
![]() |
|
Страницы: (23) « Первая ... 13 14 [15] 16 17 ... 22 23 ( Перейти к последнему сообщению ) |
Прикр. сообщ.
#1
,
|
|
|
Сообщ.
#211
,
|
|
|
Причем здесь принцип обратной совместимости?
Ошибок нет - нет фич. Насколько я понял, это только для D.NET. |
![]() |
Сообщ.
#212
,
|
|
для записей - поддерживается. |
Сообщ.
#213
,
|
|
|
Цитата jack128 @ для записей - поддерживается. Почему только для записей? http://edn.embarcadero.com/article/34324 Или перегрузка имеется ввиду перегрузка функции оператора в наследнике? |
Сообщ.
#214
,
|
|
|
Цитата alexeis1 @ Почему только для записей? http://edn.embarcadero.com/article/34324 Покажи пример. У меня Цитата Embarcadero® Delphi® 2010 Version 14.0.3513.24210 Копи-паст из примера в ссылке: ![]() ![]() type TMyClass = class class operator Implicit(a: Integer): TMyClass; // Implicit conversion of an Integer to type TMyClass : Unit1.pas(26) class operator Implicit(a: TMyClass): Integer; // Implicit conversion of TMyClass to Integer : Unit1.pas(27) class operator Explicit(a: Double): TMyClass; // Explicit conversion of a Double to TMyClass : Unit1.pas(28) end; Итог: Цитата ... [DCC Error] Unit1.pas(26): E2123 PROCEDURE, FUNCTION, PROPERTY, or VAR expected [DCC Error] Unit1.pas(26): E2029 ',' or ':' expected but '(' found [DCC Error] Unit1.pas(26): E2029 ';' expected but ':' found [DCC Error] Unit1.pas(27): E2058 Class, interface and object types only allowed in type section [DCC Error] Unit1.pas(27): E2029 ',' or ':' expected but identifier 'Implicit' found [DCC Error] Unit1.pas(27): E2004 Identifier redeclared: 'TMyClass' [DCC Error] Unit1.pas(27): E2029 ',' or ':' expected but ';' found [DCC Error] Unit1.pas(28): E2058 Class, interface and object types only allowed in type section [DCC Error] Unit1.pas(28): E2029 ',' or ':' expected but identifier 'Explicit' found [DCC Error] Unit1.pas(28): E2029 ';' expected but ':' found ... |
Сообщ.
#215
,
|
|
|
Угу таки jack128 прав. Нет для классов. В обзорах часто не уточняют для .NET пишут или для Win32. Нашел такой коммент.
Цитата http://stackoverflow.com/questions/329359/can-i-overload-operators-for-my-own-classes-in-delphi Since there is no concept of a garbage collector in Delphi Win32, it is not possible in to have operators for classes in Delphi Win32. Действительно, если в выражении будет создан промежуточный объект, то его просто невозможно будет освободить. Такой фин с преобразованием возможен либо для стековых объектов, которые уничтожаются по выходу из блока (как в С++) или же в .NET где мусор "убирается сам". Делфи не умеет следить за памятью объектов, поэтому перегрузку разрешили только для записей. |
Сообщ.
#216
,
|
|
|
Цитата alexeis1 @ Действительно, если в выражении будет создан промежуточный объект, то его просто невозможно будет освободить. а как это связано с неприменимостью перегрузки операторов? |
Сообщ.
#217
,
|
|
|
Цитата arj99 @ а как это связано с неприменимостью перегрузки операторов? Смотри ведь приводя один объект к другому необходимо создать новый объект. Например ситуация имеем классы TA, TB, TC. Есть неявное преобразование TA->TB и TB->TC. Есть две переменные var a : TA; var a : TC; Требуется присвоить a -> с; ![]() ![]() c := TC(TB(a)); Сначала создается объект типа TB из а, затем на его основе объект типа TC, указатель c получает адрес объекта типа TC, а временный объект типа TB созданный при первом преобразовании повиснет в куче без возможности удаления. |
Сообщ.
#218
,
|
|
|
Цитата alexeis1 @ временный объект типа TB созданный при первом преобразовании повиснет в куче без возможности удаления и что? как будто современный синтаксис этого не допускает? ![]() ![]() type TIntClass = class(TObject) strict private FValue: Integer; public constructor Create(Int: Integer); function Sqr(): Integer; inline; property Value: Integer read FValue write FValue; end; { TIntClass } constructor TIntClass.Create(Int: Integer); begin inherited Create(); FValue := Int; end; function TIntClass.Sqr(): Integer; begin Result := FValue * FValue; end; function GoLooseMem(X, Y: Integer): Integer; inline; begin Result := TIntClass.Create(X).Sqr() + TIntClass.Create(Y).Value; end; initialization ReportMemoryLeaksOnShutdown := true; GoLooseMem(0, 0); Всем понятно что увидим при выходе из программы и всем понятно конечно, что в функции GoLooseMem() я написал (сказать мягко) нехорошо. Но тем не менее это написать возможно. Давайте запретим свойства и методы, они потенциально могут приводить к неудалленым из кучи объектам ![]() Каждым инструментом нужно уметь пользоваться. Если в твоем примере эти вложенные приведения явные, т.е. их написал программер - это его вина. Если в твоем примере это просто демонстрация цепочки неявных приведений - то, что, у компилятора уже магия кончилась чтоли? Что ему мешает скрыто запоминать ссылку на созданный промежуточный объект, а секцию, где он еще используется, заключить в try/finally?.. |
Сообщ.
#219
,
|
|
|
Цитата arj99 @ Что ему мешает скрыто запоминать ссылку на созданный промежуточный объект, а секцию, где он еще используется, заключить в try/finally?.. А как он об этом узнает? Смысл операторов тогда пропадает. Пиши себе обычные методы. |
Сообщ.
#220
,
|
|
|
Цитата CodeMonkey @ А как он об этом узнает? Узнает о чем? Границы блока использования промежуточного объекта? ![]() Цитата CodeMonkey @ Смысл операторов тогда пропадает. По-моему смысл в последующем удобстве программирования и лаконичности кода. Этот смысл вроде никуда не девается, не попадает... а какой другой смысл? |
Сообщ.
#221
,
|
|
|
Как программист узнает о том, что вот тут создаётся временная переменная? Компилятор создаёт туевы хучи временных переменных по коду. О 80% из них вы не подозреваете.
Цитата arj99 @ смысл в последующем удобстве программирования и лаконичности кода О каком удобстве может идти речь, если вместо записи T := B + 1, я буду вынужден использовать кучу временных переменных? Добавлено Смысл введения операторов в том, что вы можете использовать их совершенно прозрачно, не задумываясь - прямо как строки. А для этого нужен механизм автофинализации (опять таки, как для строк). Для классов этого нет. Для записей - есть. Именно поэтому мы имеем операторы для записей, но не имеем для классов. Вводить операторы для классов сейчас - бессмысленно. P.S. Насколько бы удобны были бы строки (и был ли в них тогда смысл), если бы вот это S := 'T = ' + IntToStr(T); приводило бы к утечке? А ведь тут создаётся временная переменная. |
Сообщ.
#222
,
|
|
|
Цитата CodeMonkey @ Смысл введения операторов в том, что вы можете использовать их совершенно прозрачно, не задумываясь - прямо как строки. Цитата CodeMonkey @ P.S. Насколько бы удобны были бы строки (и был ли в них тогда смысл), если бы вот это S := 'T = ' + IntToStr(T); приводило бы к утечке? А ведь тут создаётся временная переменная. Да, я как раз об этом и говорю. Я извиняюсь, наверное я ввел в заблуждение, когда в посте #218 упоминал программиста. Действительно здесь я загнался и, в поисках какие же всетаки могут быть препятствия в примере от alexeis1, представил лишнего. Совершенно не важно каким способом это написано, в любом случае это должно быть разрешено действиями компилятора. Цитата CodeMonkey @ А для этого нужен механизм автофинализации (опять таки, как для строк). Для классов этого нет. Для записей - есть. Именно поэтому мы имеем операторы для записей, но не имеем для классов. Вводить операторы для классов сейчас - бессмысленно. А вот это как раз неясно. Пример от alexeis1 допустим таков: ![]() ![]() function ConvertAToC(A: TA): TC; begin Result := TC(TB(A)); end; Компилятор должен поступить примерно так: ![]() ![]() function ConvertAToC(A: TA): TC; var B: TB; begin B := A.ExplicitToB(); try Result := B.ExplicitToC(); finally B.Free(); end; end; Что не так? Добавлено Понятно что не так ![]() |
Сообщ.
#223
,
|
|
|
arj99, сейчас объект это указатель, чего бы с ними не делали это все равно де факто должно иметь схожую функциональность, иначе программисты перестанут друг друга понимать.
В примере Цитата arj99 @ явно видно создание объекта, в случае с приведением операция что произойдет реально не очевидно.Result := TIntClass.Create(X).Sqr() + TIntClass.Create(Y).Value; Что касается ![]() ![]() function ConvertAToC(A: TA): TC; var B: TB; begin B := A.ExplicitToB(); try Result := B.ExplicitToC(); finally B.Free(); end; end; Так это нужно сначала реализовать такой механизм, обкатать. На самом деле, это всего лишь один из случаев. Может оказаться так что механизм получиться слишком сложным. Кроме того он не должен бояться многопоточности, а также правильно взаимодействовать с исключениями. Автоматическое управление памятью объектов в Delphi неплохое дело, возможно разработчики в свое время подойдут к реализации такого механизма. |
Сообщ.
#224
,
|
|
|
Цитата alexeis1 @ Так это нужно сначала реализовать такой механизм, обкатать. alexeis1, основная идея моих постов в этом разговоре - это вопрос: "так какого же... такой механизм еще не реализован?" ![]() |
Сообщ.
#225
,
|
|
|
На самом деле есть интерфейсы. И через них реализованы анонимные методы с их захватом переменных. Надо просто пристроить интерфейсы к классам. Только сделать это не так просто.
|