在销毁对象后,在表中查找指向派生类的指针

时间:2016-01-07 13:49:18

标签: c++ pointers inheritance casting

我有一个Derived类来自类Base

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

RTTI和dynamic_cast<Derived*>(base)在这一点上不可用,因为对象可能已经被破坏,或者我们可能在析构函数调用链中。

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

2 个答案:

答案 0 :(得分:2)

如果static_cast有效,那么就有可能。

Cppreference : static_cast

  

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

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

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

你能早点回复吗?

答案 1 :(得分:0)

如果基数不是虚拟的,那么从基数到派生的static_cast可能会起作用。不幸的是,如果删除的对象是另一个派生类型,那么根据标准,转换本身具有未定义的行为。非常迂腐,标准的措辞甚至使static_cast从基指针指向正确类型的现在删除的派生对象的子对象,因为严格来说,指针不再指向子对象任何事情。但实际上,只要没有取消引用转换指针,我就不会指望“按预期工作”的行为。

  

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

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