dynamic_cast from“void *”

据此, void*没有RTTI信息,因此从void*投出是不合法的,这是有道理的。

如果我没有记错, void* dynamic_cast正在gcc上工作。

你能否澄清这个问题?

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

在gcc中,你可以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 } 

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

  • 如果T是一个指针types, v应该是一个指针的右值来完成类的types
  • 如果T是一个引用types, v应该是一个完整的类types的左值(感谢usta评论我错过了这个)

  • 否则, v应该是一个多态types的指针或左值

所以,不,一个(void*) 是不允许的。

让我们考虑一下你的请求可能意味着什么:假设你有一个指向Derived1*的指针,但dynamic_cast代码只知道它是一个void* 。 假设你正试图将其转换为Derived2* ,其中派生类都有一个公共基础。 从表面上看,你可能会认为所有的指针都指向同一个Base对象,它包含一个指向相关的虚拟调度表和RTTI的指针,所以所有的东西都可以挂在一起。 但是,考虑到派生类可能有多个基类,因此所需的Base类子对象可能不是Derived*所能提供的唯一一个void*指向的类。 这是行不通的。 结论:编译器需要知道这些types,因此可以根据所涉及的types对指针进行一些调整。

 Derived1 * -----> [AnotherBase]
                  [[VDT] Base] < - 但是,需要一个指针来开始
                  [extra members] dynamic_cast的这个子对象

(有些答案提到你需要的指针是一个多态的types,具有虚函数,这一切都是有效的,但有点误导,正如你在上面看到的那样,即使void*是这样的如果没有完整的types信息,那么键入它仍然不可靠,因为真正的问题是void*可能指向派生对象的开始,而您需要一个指向基类子对象的指针,types派生。)

的确, void*不能被dynamically_cast从中进行编辑。

你可能是错误的记忆。 用g ++ 4.5和下面的代码

 struct A { virtual ~A(); }; int main() { A a; void *p = &a; A* pa = dynamic_cast<A*>(p); } 

我得到以下错误:

不能dynamic_cast'p'(types'void *')键入'struct A *'(源不是指向类的指针)

我想你会迷惑dynalic_cast void* 。 这是合法的,并获得最派生类对象的指针。

void* dynamic_cast是非法的 – 从types转换的types必须是多态的 – 至less包含一个虚函数(虚析构函数也是如此)。

你可以将一个指针指向多态types来void * ,但反之亦然。