【问题标题】:What is the equivalent of dynamic_cast in Delphi?Delphi中的dynamic_cast等价物是什么?
【发布时间】:2019-03-09 22:10:58
【问题描述】:

在 Delphi 中,什么是 C++ 的 dynamic_castreinterpret_caststatic_cast 运算符(尤其是用于对象时)?

【问题讨论】:

    标签: c++ delphi c++builder


    【解决方案1】:

    reinterpret_cast

    大多数时候,在 Delphi 中,强制转换是 reinterpret_cast,即一种类型的位和字节被重新解释为另一种类型,例如Integer(myEnum)Pointer(MyDynamicArrayVar)

    一些强制转换会截断位,即Integer(MyInt64) 将截断Int64 的前32 位,而低32 位的高位将成为新的符号位。一些演员表扩展,例如Integer(myByte),尽管此类转换为更大的类型不需要强制转换。转换,例如Integer 到浮点数也不需要强制转换。

    但有时它不是reinterpret_cast,并且转换进行了真正的转换(例如,如果字符串为空,则从string 转换为PChar;从AnsiString 转换为UTF8String 转换将内容转换为 UTF-8,UnicodeString(myAnsiChar) 甚至会转换两次,从 AnsiCharAnsiStringUnicodeString,尽管这些步骤可能并非全部可见)。并且某些演员表根本不允许(例如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 ...
    

    查询,就像 C++ 中经常使用 dynamic_cast 完成的一样,可以使用 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!";
    

    【讨论】:

    • 在多态的情况下,对象的dynamic_cast 有一个直接等价物 - the is and as operatorsif obj is T then 等价于if (dynamic_cast&lt;T*&gt;(obj) != NULL)obj as T 等价于T* pT = dynamic_cast&lt;T*&gt;(obj); if (pT == NULL) throw ...;
    • @RemyLebeau 或只是&amp;dynamic_cast&lt;T&amp;&gt;(*ptr)
    • 在您的答案中添加硬转换会很好。例如myEdit := TEdit(MyTObject) 类似于 static_cast 但用于对象。
    • @Yakk-AdamNevraumont touché :-)
    猜你喜欢
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多