如何从 Base 析构函数中将 Base* 与 Derived* 列表进行匹配?

How can I match Base* against a list of Derived*, from within Base destructor?

我有两个 类、BaseDerived。我有一个存储 Derived* 指针列表的容器。

有一个 signal/slot 机制在 Base 对象被销毁时发出信号,此时我们在 ~Base 析构函数中,因此 RTTI 不可用于转换 Base*Derived*(这是使用 Qt,但问题不是特定于 Qt 的)

该信号连接到管理指针容器的插槽。你可能已经猜到了,我想检查对象被销毁的 Base* 指针是否对应于容器内部存储的 Derived* 指针,如果是,则将其从容器中移除。

我知道有很多替代设计,例如不使用 QObject::destroyed() 信号,或者存储 QObject* 列表而不是 Derived*。但出于许多实际原因,我想使用那个。

这意味着,我想将基指针转换为派生指针,不是为了解除引用,而是为了取消跟踪指针,我希望它是定义的行为,无论子类树是什么(包括多重继承、虚函数...).

我可以使用 static_cast 吗?

谢谢!

您可以为容器的每个元素使用 static_castbase 类型,并将其与您的 *base ptr 进行比较。这样你就可以找到对象了。

class Base;
class Derived;
std::vector<Derived*> arrDerived;

void Remove(Base* pBase);

class Base
{
public:
    ~Base()
    {
        Remove(this);
    }
};

class Derived : public Base
{

};

void Remove(Base* pBase)
{
    for (Derived* pDerived : arrDerived)
    {
        //if (static_cast<Base*>(pDerived) == pBase) same as
        if (pDerived == pBase)
        {
            //you found it!!!!
            return;
        }
    }
}

当您执行 static_cast<Base*>(Derived) 时,编译器只是将 ptr 移动一些 const 内存量较低(因此它指向基础 class)。因此,此操作与实际内存状态无关,对您来说 safe

编辑:正如@a​​lain 提到的,您可以在没有 static_cast 的情况下进行比较 - 它会自动执行。

您在评论中写道:

comparing the cast pointer to a table Derived* pointers for removing it. Of course I will not dereference the cast pointer.

在这种情况下,根本不需要转换,你可以直接比较你的指针:

Base* base;
Derived* derived;
if(base == derived) {
}