【问题标题】:Use dynamic_cast to to validate pointer to polymorphic type使用 dynamic_cast 来验证指向多态类型的指针
【发布时间】:2016-01-14 12:14:20
【问题描述】:

由于某些原因,我们的应用程序中的指针可能已经被删除:

IPolymorphicObject* p_object = CreateObject();

某处 p_object 将被删除(通过 delete 或卸载分配它的模块)

delete p_type;

另一个使用 p_object 保存值的代码,让它成为 mp_object

mp_object->SomeMethod();

由于 mp_object 已被删除 - 我们发生了崩溃。 我知道最好的方法是切换到shared_ptr/weak_ptr,但是现在它需要大量的重构,这就是为什么我找到了另一个解决方案——如何检查指针的有效性。

我知道 dynamic_cast 将返回指向内存中实际对象偏移量的指针。

我也知道 dynamic_cast(p_invalid_pointer) 会抛出一个异常 non_rtti_object 我可以捕捉到我因此编写验证方法:

template<class T>
bool IsPointerValid(T* ip_ptr)
{
try
{
dynamic_cast<void*>(ip_ptr);
}
catch(...)
{
return false;
}

return true;
}

最终代码如下所示:

if(IsPointerValid(mp_object)) mp_object->SomeMethod();

我知道这将是一个非常糟糕的解决方案,应该避免。

我的问题是:如果指向多态对象的指针无效,IsPointerValid 是否总是返回 false?

【问题讨论】:

  • 我强烈怀疑你在这个世界的任何保证之外!绝对是语言标准。可能是通过执行。无论如何,它是哪个实现?
  • 你添加了 C 标签 - 为什么? C 不是 C++ 不是 C!
  • 以任何方式使用杂散指针,除了重新初始化它(即分配它指向有效的东西)总是会导致未定义的行为
  • 即使你发现指针中包含了某个“多态对象”的地址,它也很可能是某个new对象碰巧重用了被删除对象的内存空间。
  • 我使用 Visual Studio 2013 x64 库中的 dynamic_cast 实现。对于所有具有无效指针的情况,它都运行良好。但我知道它确实是特定于实现的,并且取决于编译器/链接器/目标平台。我发现在 Linux 上它会崩溃,因为指针指向已经空闲的内存。

标签: c++ pointers casting


【解决方案1】:

这是未定义的行为。

您需要了解的是dynamic_cast 需要一个“有效”指针。也就是说,一个指向“有效”对象的指针。

给定一个指向无效对象的指针,一个不再存在的对象,这会导致未定义的行为。

有时你会在这里得到真实的。有时你会弄错。有时你会得到"File Not Found" 作为返回值。这就是未定义行为的含义。

【讨论】:

    【解决方案2】:

    虽然迁移到shared/weak_ptr 肯定会花费您很多时间,但解决问题并保证不会返回,会花费您

    一个。更多时间;你将永远处于“我认为问题已解决”的状态,再也不会感到安全了。

    b.客户满意度,因为您不会 100% 覆盖源代码。

    【讨论】:

      【解决方案3】:

      我希望您在取消引用之前也有 NULL 指针检查。在这种情况下,用宏 DELETE 替换您的删除,这将调用真正的删除并将指针设置为 NULL。这将向后续软件发出该对象已删除且不应使用的信号。在我看来,这样的替换在一个相对较大的项目中也不应该花费很大的精力。

      【讨论】:

      • 如果你仔细阅读这个问题,它说明指针的早期副本已经制作。在删除后将指针设置为 NULL,就影响其他不相关的指针而言,绝对不会有任何效果。
      • 啊.. 只是缺少“使用保存的值”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      • 2012-10-19
      • 2018-05-25
      • 2021-12-04
      • 2015-04-06
      相关资源
      最近更新 更多