在Delphi中,dynamic_cast的等效物是什么?

6
在 Delphi 中,与 C++ 的 dynamic_cast、reinterpret_cast 和 static_cast 运算符相等的是什么(特别是在对象上使用时)?
1个回答

9

reinterpret_cast

在Delphi中,大部分情况下,类型转换是一个 reinterpret_cast,也就是将一种类型的位和字节重新解释为另外一种类型,例如 Integer(myEnum)Pointer(MyDynamicArrayVar)

有些类型转换会截断一些位,比如 Integer(MyInt64) 会截断 Int64 的顶端32位,并且保留剩余32位中的顶端位作为新的符号位。还有些类型转换会扩展类型,例如 Integer(myByte),虽然这种从小类型到大类型的转换不需要进行类型转换。从 Integer 到浮点数之类的转换也不需要进行类型转换。

但有时候并不是一种 reinterpret_cast,而是真正的转换(例如从 stringPChar 的转换,如果字符串为空则不进行转换;从 AnsiStringUTF8String 的转换将内容转换为 UTF-8 编码,以及 UnicodeString(myAnsiChar) 的转换甚至进行了两次,从 AnsiCharAnsiString,再从 AnsiStringUnicodeString,尽管这些步骤中的某些步骤可能不可见)。有些转换是不允许的(例如 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

如果涉及的类型是类或接口,则可以使用asis关键字进行等效转换。例如:

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

两者都是动态向上转型。与C++不同的是,如果MyTObject不是TEdit的实例,或者myObj没有实现ISomeInterface,则会引发(在C++中抛出)EInvalidCast异常。否则,它与C++等效:

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

在IT技术中,我们常常使用C++的dynamic_cast来查询信息,而在Python中,我们可以使用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!";

1
在多态的情况下,对象有一个直接等价于 dynamic_cast 的操作符 - isas 操作符if obj is T then 相当于 if (dynamic_cast<T*>(obj) != NULL),而 obj as T 相当于 T* pT = dynamic_cast<T*>(obj); if (pT == NULL) throw ...; - Remy Lebeau
1
@RemyLebeau 或者只需 &dynamic_cast<T&>(*ptr) - Yakk - Adam Nevraumont
2
最好在你的答案中添加硬转换。例如:myEdit := TEdit(MyTObject),这就像是对象的 static_cast - Graymatter
@Yakk-AdamNevraumont 见笑了 :-) - Remy Lebeau

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接