gpt4 book ai didi

c++ - 在什么情况/情况下 dynamic_cast<> 会失败?

转载 作者:搜寻专家 更新时间:2023-10-31 01:16:16 29 4
gpt4 key购买 nike

在修复庞大代码库中的错误时,我观察到一个奇怪的情况,其中引用的动态类型从原始 Derived 类型更改为 Base 类型!我提供了最少的代码来解释问题:

struct Base {
// some 'virtual' function
protected: // copy constructor
private: // assignment operator
};

struct Derived : Base {
... // There are few more classes between `Base` and `Derived`
... // but for simplicity, I have put direct relation
};

void foo (Base &ref)
{
SomeClass obj;
obj.pVoid = &ref; // pVoid is of void*

// ----> typeid(ref) = Derived
(*funcptr)(obj);
// ----> typeid(ref) = Base !!!

Derived *p = dynamic_cast<Derived*>(&ref); // this fails ... i.e. "p = 0"
}

funcptr 是一个函数指针 (void (*)(SomeClass&))。 funcptr 可以指向这么多的函数,并且它们有自己的调用流程,因此很难调试。

很奇怪,调用函数指针后,ref的派生类型从Derived变成了Base。为了简化我的工作,我怀疑对象从 Derived 切片到 Base,所以我将 ~Base() 设为纯 virtual 并重新编译了整个源代码。但是没有编译器错误,这意味着没有声明 Base 的对象。

ref Derived 的动态类型更改为 Basedynamic_cast 的潜在原因是什么> 后来失败了?

最佳答案

我不相信上面的代码是真的,因为代码示例没有编译!您不能隐式转换 Base*来自 dynamic_cast<Base*>(&ref)Derived* .

这就是说并假设 typeid() 的输出实际上是正确的对于引用更改的类型 ID 有一些可行的解释。所有这些都表明程序中存在某种形式的错误:

  1. 被调用函数销毁对象,例如通过调用 dynamics_cast<Base*>(obj.pVoid)->~Base() 的道德等价物.
  2. 被调用函数在obj.pVoid指向的地址构造一个新对象使用展示位置 new ,即像这样的东西:new(obj.pVoid) Base() .
  3. 某些东西正在覆盖内存,导致留下 Base引用位置中的对象。
  4. 可能还有更多原因......

就我个人而言,我会赌第二种情况是情况,即一个对象被构建到该位置。显然,如果没有看到被调用的函数,就无法分辨。

关于c++ - 在什么情况/情况下 dynamic_cast<> 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9238711/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com