来自"void*"的dynamic_cast

dim*_*mba 35 c++ dynamic-cast rtti void-pointers

根据这个,void*没有RTTI信息,因此从铸造void*是不合法的,它是有意义的.

如果我没记错的话,dynamic_castvoid*正在开发gcc.

你能澄清一下这个问题吗?

vit*_*aut 42

dynamic_cast 仅适用于多态类型,即包含虚函数的类.

在海湾合作委员会,你可以dynamic_cast void*,但不:

struct S
{
    virtual ~S() {}
};

int main()
{
    S* p = new S();
    void* v = dynamic_cast<void*>(p);
    S* p1 = dynamic_cast<S*>(v); // gives an error
}
Run Code Online (Sandbox Code Playgroud)


Ton*_*roy 16

5.2.7 - Dynamic cast [expr.dynamic.cast]其中说dynamic_cast<T>(v):

  • 如果T是指针类型,则v应该是指向完成类类型的指针的右值
  • 如果T是引用类型,则v应该是完整类类型的左值(感谢usta对我的遗漏进行评论)

...

  • 否则,v应该是指向多态类型的左值或左值

所以,不,不允许使用(void*) .

让我们考虑一下你的请求可能意味着什么:说你有一个真正意义上的指针Derived1*,但代码dynamic_cast只知道它是一个void*.假设您正在尝试将其转换为a Derived2*,两个派生类都有一个共同的基础.从表面上看,您可能认为所有指针都指向同一个Base对象,该对象包含指向相关虚拟调度表和RTTI的指针,因此所有内容都可以挂起.但是,请考虑派生类可能有多个基类,因此所需的Base类子对象可能不是Derived*- 只能作为void* - 指着.它不会起作用.结论:编译器需要知道这些类型,以便它可以根据所涉及的类型对指针进行一些调整.

Derived1* -----> [AnotherBase]
                 [[VDT]Base]    <-- but, need a pointer to start of
                 [extra members]    this sub-object for dynamic_cast

(有些答案谈到你需要将你所指向的指针变成多态类型,具有虚函数.这都是有效的,但有点误导.正如你在上面所看到的,即使void*是这样的类型它如果没有完整的类型信息,仍然无法可靠地工作,因为真正的问题是void*大概指向派生对象的开始,而你需要一个指向基类子对象的指针,从中派生类型派生. )


Mot*_*tti 5

确实void*无法dynamically_cast编辑。

你可能记错了。使用 g++ 4.5 和以下代码

struct A {
    virtual ~A();
};

int main() {
    A a;
    void *p = &a;
    A* pa = dynamic_cast<A*>(p);
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

无法将“p”(类型为“void*”)动态转换为类型“struct A*”(源不是指向类的指针)