dynamic_cast不能保证一个有效、完整的对象?

dynamic_cast doesn't guarantee a valid, complete object?

本文关键字:有效 一个 对象 不能 cast dynamic      更新时间:2023-10-16

我正在阅读此页面,它说

dynamic_cast只能与指针和对对象的引用一起使用。其目的是确保类型转换的结果是所请求类的有效完整对象。

但是当我这样做时,dynamic_cast没有给出一个有效的对象:

struct A{};
struct B:A{};
void main(){
    A a;
    B b;
    B* bPtr = (B*) 0x0000001;
    A* aPtr = dynamic_cast<A*>(bPtr);
    //Now aPtr is the memory address 0x00000001
}

由于 bPtr 不包含有效的 A 对象,因此我希望dynamic_cast无法通过此转换,以便 aPtr 将变为 NULL。但这没有发生吗?哪一个是错误的,编译器(g++ 4.5.7)还是上面提到的网页?还是我错过了dynamic_cast实际上应该做什么?

编辑:答案摘要

  1. 在上层中,dynamic_cast什么都不做。没有任何形式的保证。
  2. 在向下投掷中,dynamic_cast 不会检查错误的指针。它假定源指针为 0 或指向有效的源对象。(如果给出错误的指针,则dynamic_cast操作可能会在向下转换期间出现段错误)
  3. 向下转换到dynamic_cast需要基类中至少有一个虚拟成员。

dynamic_cast<>保证给出一个有效的对象,前提是它被正确使用。

使用此强制转换的第一个要求是具有多态基类(至少 1 个virtual函数)。在您的示例中,AB 不是多态的,这将导致编译错误。

第二个要求dynamic_cast<>应该用于向下转换,在您的情况下,您将其用于向上转换(这很容易发生)。

假设它们是多态的,那么第三个要求是在指向正确对象的指针/引用上使用此强制转换。
bPtr = (B*)0x0000001不能保证引用B的对象(主要是 UB)。

下面是正确的示例:

struct A{ virtual ~A() {} };
struct B : A {};
void main(){
  A* pA = new B;
  B* pB = dynamic_cast<B*>(pA);
}
相关文章: