在Delphi中,C ++的dynamic_cast
,reinterpret_cast
和static_cast
运算符(特别是在对象上使用)的含义是什么?
答案 0 :(得分:9)
大多数时候,在Delphi中,强制类型转换是reinterpret_cast
,即一种类型的位和字节被重新解释为好像是另一种类型,例如Integer(myEnum)
或Pointer(MyDynamicArrayVar)
。
某些强制转换会切断位,即Integer(MyInt64)
将切断Int64
的高32位,而低32位的高位将成为新的符号位。一些演员阵容会扩大,例如Integer(myByte)
,尽管这种转换为较大的类型不需要强制转换。转化来源,例如Integer
到浮点也不需要强制转换。
但是有时它不是reinterpret_cast
,并且强制转换会进行真正的转换(例如,如果字符串为空,则从string
到PChar
的强制转换;从{{ 1}}到AnsiString
会将内容转换为UTF-8,并且UTF8String
甚至转换两次,从UnicodeString(myAnsiChar)
到AnsiChar
再到AnsiString
,尽管这些步骤可能并非所有人都可见)。而且根本不允许使用某些类型的转换(例如UnicodeString
或大小不匹配的某些类型的转换)。
请注意,在运算符重载(主要用于记录)的情况下,您也可以进行显式和隐式转换。显式转换采用强制转换的形式。隐式转换也可以通过“强制转换”来强制执行。
在Delphi中,强制转换的形式始终为Int64(MyDouble)
,它将typename(cast_object)
强制转换为cast_object
。
可以使用指针规避一些无效的强制转换。如果您执行以下操作:
typename
其中MyInt64 := PInt64(@MyDouble)^;
是指向PInt64
的指针,其他类型很明显,
然后可以将Int64
强制转换为Double
。请注意,没有实际的指针变戏法。转换是直接的,就好像您完成一样
Int64
Delphi中没有MyInt64 := Int64(MyDouble); // Invalid typecast -- except in some versions
的额外种类。我个人希望我们能像在C ++中那样进行明确的转换。 Delphi更像是C语言。
如果涉及的类型是类或接口,则使用static_cast
和as
关键字是等效的。例如:
is
两者都是动态的。与C ++不同,如果myEdit := MyTObject as TEdit;
myIntf := MyObj as ISomeInterface;
不是EInvalidCast
的实例,或者MyTObject
不是实现的话,它们将引发(抛出C ++)一个TEdit
异常。 myObj
。在其他方面,它等效于C ++:
ISomeInterface
查询(通常在C ++中使用TEdit *myEdit = dynamic_cast<TEdit *>(MyTObject);
if (myEdit == NULL) throw ...
完成)可以通过dynamic_cast
完成:
is
这与C ++中的“模式”大致相同:
if MyObject is TEdit then
TEdit(MyObject).Text := 'Hello, world!';