Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

явное приведение и AS

286
26 октября 2007 года
misha_turist
572 / / 28.11.2005
Вот недавно отвечал я в теме Составное имя компонента и предложил строку (<перевенная> as <класс>).<поле>, но мне ответили, что лучше использовать <класс>(<перевенная>).<поле> из за выигрыша в скорости.

Вот меня и заинтересовал вопрос в чём отличае этих опираций в чём каждая из них лучше/хуже?

Сзаранее спасибо за дискуссию. :)
276
26 октября 2007 года
Rebbit
1.1K / / 01.08.2005
С того что недавно читал по .НЕТу (думаю в Делфи оно не очень отличается)

При явном приведении может возникнуть ексепшен если привести не удастся.
В .НЕТе есть is - проверить можно ли привести (в некорых языках instanceof). Результат операции - логический тип.
 
Код:
if (obj is MyClass) {
  MyClass mobj = (MyClass)obj;
}
Но при таком использовании приведение типа, которое происходит достаточно долго выполняется два раза: в проверке и при приведении непосредственно.

as - попробует привести тип и если ето удастса вернен переменную нужного типа, в противном случае вернет null. Потом проверяется значение переменной на null, что гараздо быстрее чем is.
 
Код:
MyClass mobj = obj as MyClass
if (mobj != null) {
  чтото делаем
}
Вроде так там было написано.
Приведение делается один раз и ексепшен не произойдет. Разве что не проверить на null и исипользовать. Но тогда ексепшен будет уже другой.

Собственно я вижу разницу только в том что при as не должен генерится ексепшен.
Причину возможной разници в быстродействии я не вижу, так что самому хотелось бы узнать. Надеюсь ahilles заметит тему и прольет свет на вопрос.
268
26 октября 2007 года
Михаил
587 / / 25.06.2005
при простом приведении типов проверки на совместимость не производится, т.е. можно приводить к друг другу совершенно разные классы, а as проверяет совместимы ли классы, вроде так
276
26 октября 2007 года
Rebbit
1.1K / / 01.08.2005
Цитата: Михаил
при простом приведении типов проверки на совместимость не производится, т.е. можно приводить к друг другу совершенно разные классы, а as проверяет совместимы ли классы, вроде так


Тоесть в Делфи при простом приведении вобще можно что хочеш сделать ? А когдаже ошибка вылезет ? При испольновании обекта ?

ЗЫ. Кстати Михаил, с полсотней постов тебя. :)

268
26 октября 2007 года
Михаил
587 / / 25.06.2005
может и не возникнуть если память будет уже выделена
к примеру можно сделать так:
Код:
type tc=class
procedure msg;
end;

procedure tc.msg;
begin
ShowMessage(string(self));
end;

var s:string;

s:='ggg';
tc(s).msg;


вот так
276
26 октября 2007 года
Rebbit
1.1K / / 01.08.2005
Цитата: Михаил
может и не возникнуть если память будет уже выделена
вот так


Гы. Забавно, неужели плохой код столько пророботать может. А если в msg к полям обекта обратится ?
Извените что надоедаю. Я как всегда на роботе и без средств розроботки под Делфи. Попробовать негде.

268
26 октября 2007 года
Михаил
587 / / 25.06.2005
обращения к полям производится начиная с адреса Self+4
276
26 октября 2007 года
Rebbit
1.1K / / 01.08.2005
Цитата: Михаил
обращения к полям производится начиная с адреса Self+4


Жуть :). Так как же убить такой код ?
Ети четыре байта возможно адрес карты виртуальных методов ? Может тогда виртуальный метод вызвать чтоб ета прога накрылась ?
А то я сейчас вижу только две причини смерти: обращение к памяти только для чтения и выполнения недопустимой операцыи. По сути если обратится к виртуальному методу, то управление должно перейти чиртикуда.

261
28 октября 2007 года
ahilles
1.5K / / 03.11.2005
Цитата: Rebbit
Надеюсь ahilles заметит тему и прольет свет на вопрос.



в общем не хочу сам мучаться и писать об этом, приведу цитату из книги Марко Кэнту "Delphi 7: для профессионалов "

Цитата:
оба RTTI-оператора очень полезны в Delphi, поскольку довольно часто возникает необходимость написать общий программный код, который может использоваться в нескольких компонентах одного типа или даже разных типов. При передаче компонента в качестве параметра в метод, реагирующий на событие, используется общий тип данных (TObject); поэтому зачастую необходимо привести его обратно к исходному типу компонента:
procedure TForm1.ButtonlClick(Sender: TObject);
begin
if Sender is TButton then
end;
В Delphi это довольно обычная практика, и я буду использовать ее в примерах этой книги. Два RTTI-оператора, is и as, чрезвычайно мощны, что может ввести в заблуждение: вы будете воспринимать их как стандартные конструкции программирования. Хотя они действительно мощны, необходимо ограничивать их использование только в исключительных случаях. При необходимости решить сложную проблему, включающую несколько классов, пробуйте сначала использовать полиморфизм. Только в отдельных случаях, где один полиморфизм не справляется, можно пробовать использовать RTTI-операторы. Не используйте RTTI вместо полиморфизма. Это неправильная практика программирования, которая ведет к снижению скорости выполнения программ. RTTI-операторы отрицательно влияют на производительность, поскольку для того, чтобы увидеть, является ли приведение типов корректным, им приходится пройти по всей иерархии классов. Как вы уже видели, вызовы виртуального метода требуют лишь поиска в памяти, что осуществляется гораздо быстрее.



P.S. если надо попроще, то вот что я про это писал когда был чайником :) _http://programmersclub.ru/is-as-gruzin :)

309
29 октября 2007 года
el scorpio
1.1K / / 19.09.2006
Простое приведение типа для указателей выполняется моментально, но при неверном типе исходных данных, результат будет непредсказуемым. Соответственно, используется только там, где у разработчика полная уверенность невозможности появления иных данных. Например список TList или TStrings, который в программе заполняется однотипными данными.

Операция is выполняет проверку соответствия типов и возвращает true или false. Если проверка прошла удачно, то можно использовать простое приведение
Операция as возвращает адрес или nil. Если проверка тиов прошла неудачно, то без проверки адреса неизбежно будет исключение "Ошибка доступа" (по нулевому адресу)

Кроме того, если исходные данные переданы ссылкой типа TObject, для проверки допустимости приведения можно использовать метод InheritsFrom (Другой_Тип). Либо его статичную реализацию TObject.InheritsFrom (Исходная_ссылка, Другой_Тип).
286
29 октября 2007 года
misha_turist
572 / / 28.11.2005
То-есть получается конструкция
 
Код:
if sender is TMyClass then TMyClass(sender).______;
ошибок вызвать не должна в любом случае и использование as в данном случае не обязательно?
309
30 октября 2007 года
el scorpio
1.1K / / 19.09.2006
as в данном вопросе будет напрасным дублированием проверки.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог