【问题标题】:Casting with multiple inheritance多重继承铸造
【发布时间】:2010-07-25 01:27:42
【问题描述】:

如果你有一个指向 Derived 类的 void* 指针,它继承自 BaseABaseB,编译器如何在不知道 @ 987654326@指针的类型是Derived?

【问题讨论】:

    标签: c++ casting multiple-inheritance


    【解决方案1】:

    它没有。使用static_castvoid* 进行转换时的唯一保证是:

    指向对象的指针类型的值转换为“指向cv void”并返回到原始指针类型的值将具有其原始值(C++03 §5.2.9/10)。

    例如,以下代码不正确,因为void* 被强制转换为原始指针类型以外的类型(强制转换顺序为B1* -> void* -> B2*):

    struct B1 { int i; };
    struct B2 { int j; };
    
    struct D : B1, B2 { };
    
    D x;
    B1*   b1ptr   = &x;
    void* voidptr = b1ptr;
    B2*   b2ptr   = static_cast<B2*>(voidptr);
    

    尝试在此处使用b2ptr 会导致未定义的行为。您可以安全地将voidptr 转换为的唯一类型是B1*,因为这是获得void* 的类型(好吧,或者是char*,因为任何东西都可以通过char* 访问)。

    【讨论】:

      【解决方案2】:

      编译器不会将void* 指针转换为任何东西——你,程序员,做的。

      为了对void* 指针做任何有用的事情,您需要显式将其转换为非void* 指针,如果您对指针的实际类型有误指向,你进入未定义行为城市。

      【讨论】:

      • 你的答案是正确的。根据我的研究,如果 Derived 扩展 BaseA 和 BaseB,则对象在内存中布局为 |BaseA|BaseB|Derived|。因此,指针指向 BaseA 的开头,因此将 Derived 转换为 BaseB 将使您读取 BaseA 的成员。
      猜你喜欢
      • 2021-06-14
      • 2011-08-01
      • 2013-01-25
      • 2018-05-12
      • 2020-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多