【问题标题】:Find pointer to derived class in a table after the object was destroyed对象被销毁后在表中查找指向派生类的指针
【发布时间】:2016-01-07 13:49:18
【问题描述】:

我有一个从 Base 类派生的 Derived 类

我有一个 Derived* 指针(例如向量、集合等)的 std:: 容器。我有一个Base* 指针,我想知道容器是否包含该指针。

RTTI 和 dynamic_cast<Derived*>(base) 在此时不可用,因为对象可能已经被销毁,或者我们可能在 Destructor 调用链中。

如何检查容器是否包含基指针?

【问题讨论】:

  • 说实话,这听起来像是一个糟糕的设计。
  • @CoryKramer :这听起来像是无用的评论,因为您不知道上下文(使用的框架等......)
  • @Rabbid76 :因为我需要访问派生对象。这些实际上是 QObjects 子类 (Qt),如果您熟悉 Qt,我会收到“destroyed()”信号。
  • 你在向人们寻求帮助,然后批评他们不知道你没有提供的细节。不要那样做。如果你的问题不完整,那是你的错,你需要解决它。

标签: c++ pointers inheritance casting


【解决方案1】:

如果static_cast 有效,那么它是可能的。

Cppreference : static_cast 。

如果 new_type 是指向某个类 D 的指针或引用,并且表达式的类型是指向其非虚拟基 B 的指针或引用,则 static_cast 执行向下转换。这样的 static_cast 不进行运行时检查以确保对象的运行时类型实际上是 D,并且只有在通过其他方式(例如实现静态多态性时)保证此前提条件时才能安全使用。可以使用 dynamic_cast 进行安全向下转换。

没有检查,所以 static_cast 应该做出正确的指针调整。

reinterpret_cast 依赖于 &base == &derived static_cast 允许编译器在派生类不在对象开头时返回对基的调整。

你能让回调更早发生吗?

【讨论】:

  • 我有 100 种不同的方法,是的。我可能会。我只想回答知识问题。
  • 是的,我终于用了一个更早的回调,一个finished()信号而不是一个destroy()信号,finished()信号无论如何都会触发其他地方的对象销毁。
【解决方案2】:

如果基础不是虚拟的,那么从基础到派生的static_cast 可能会起作用。不幸的是,如果删除的对象是另一个派生类型,那么根据标准,转换本身具有未定义的行为。由于非常迂腐,标准的措辞甚至使static_cast 来自一个指向正确类型的已删除派生对象的子对象的基指针,因为严格来说,指针不再指向任何东西的子对象.但在实践中,只要未取消引用强制转换的指针,除了“按预期工作”之外,我不会期待任何其他行为。

如果类型“cv1 B”的对象实际上是类型D对象的子对象,则结果引用类型D的封闭对象。否则,行为未定义。

我建议考虑防止这种情况发生的方法。在对象被实际删除之前从析构函数或之前发送回调将允许使用dynamic_cast。另一种选择是将基指针存储在集合中。如果您已正确封装集合(并且基不是虚拟的),那么您可以安全地将集合中的指针static_cast 转换为派生指针。

【讨论】:

    猜你喜欢
    • 2012-11-30
    • 2021-05-20
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    • 2011-11-04
    相关资源
    最近更新 更多