Что эквивалентно dynamic_cast в Delphi? - PullRequest
0 голосов
/ 04 октября 2018

В Delphi, что эквивалентно операторам C ++ dynamic_cast, reinterpret_cast и static_cast (особенно при использовании на объектах)?

1 Ответ

0 голосов
/ 04 октября 2018

reinterpret_cast

Большую часть времени в Delphi приведение является reinterpret_cast, то есть биты и байты одного типа переинтерпретируются, как если бы это был другой тип, например Integer(myEnum) или Pointer(MyDynamicArrayVar).

Некоторые броски обрезают биты, т. Е. Integer(MyInt64) обрезает верхние 32 бита Int64, а верхний бит младших 32 битов становится новым знаковым битом.Некоторые броски расширяются, например, Integer(myByte), хотя такие преобразования в больший тип не требуют приведений.Преобразования из, например, Integer в число с плавающей запятой также не требуют приведения.

Но иногда это не reinterpret_cast, и приведение выполняет реальное преобразование (например, приведение из string в PChar преобразуется, если строка пуста, приведение от AnsiString до UTF8String преобразует содержимое в UTF-8, а UnicodeString(myAnsiChar) преобразует даже дважды, от AnsiChar до AnsiString до UnicodeString, хотя этишаги не все могут быть видны).А некоторые приведения просто недопустимы (например, Int64(MyDouble) или определенные приведения, где размеры не совпадают).

Обратите внимание, что при перегрузке операторов (в основном для записей) вы также можете иметь явные и неявные преобразования.Явные преобразования принимают форму приведения.Неявные преобразования также могут быть принудительно вызваны «приведением».

Форма преобразования в Delphi всегда typename(cast_object), что приводит к cast_object к typename.

Некоторые недопустимые приведенияможно обойти с помощью указателей.Если вы сделаете что-то вроде:

MyInt64 := PInt64(@MyDouble)^;

, где PInt64 - указатель на Int64, а другие типы очевидны ,

, тогда вы можете разыгратьDouble до Int64.Обратите внимание, что фактическое жонглирование указателя не выполняется .Преобразование является прямым, , как если бы вы сделали

MyInt64 := Int64(MyDouble); // Invalid typecast -- except in some versions

В Delphi нет никакого дополнительного вида static_cast.Я лично хотел бы, чтобы у нас были такие явные приведения, как в C ++.Delphi больше похож на C.

dynamic_cast

Если задействованы типы классов или интерфейсов, то есть эквиваленты, использующие ключевые слова as и is.Например:

myEdit := MyTObject as TEdit;
myIntf := MyObj as ISomeInterface;

оба динамических повышения.В отличие от C ++, они вызовут (сгенерирует в C ++) исключение EInvalidCast, если MyTObject не является экземпляром TEdit или если myObj не реализует ISomeInterface.В противном случае это эквивалентно C ++:

TEdit *myEdit = dynamic_cast<TEdit *>(MyTObject);
if (myEdit == NULL) throw ...

Запросы, как это часто делается с dynamic_cast в C ++, могут выполняться с помощью is:

if MyObject is TEdit then
  TEdit(MyObject).Text := 'Hello, world!';

Это более или менееэквивалентно этому «шаблону» в C ++:

TEdit *e = dynamic_cast<TEdit *>(MyObject);
if (e != NULL)
    e->Text = "Hello, world!";
...