C++ 使用多重继承与未知基比较指针 class

C++ comparing pointers using multiple-inheritance with unknown base class

我有两个 std::vector 指向 类 AB 的指针,我正在尝试创建一个从这些向量中删除对象的方法。该对象可以是也可以不是 A and/or B 的子类,并且不必是任何向量的元素。我试过以下代码:

void removeObject(void *object) {
    A *pa = static_cast<A*>(object);
    std::vector<A*>::iterator aPos = std::find(as.begin(), as.end(), pa);
    if (aPos != as.end())
        as.erase(aPos);
    B *pb = static_cast<B*>(object);
    std::vector<B*>::iterator bPos =  std::find(bs.begin(), bs.end(), pb);
    if (bPos != bs.end())
        bs.erase(bPos);
}

但是指针有不同的值,所以 std::find 不起作用(或者更确切地说它起作用 有时 )。阅读 Multiple inheritance pointer comparison and C++ pointer multi-inheritance fun 后,我明白了原因,但在这两种情况下,建议的解决方案都是将指针转换为 *subclass。我的问题是:

  1. 如何检查两个指针​​是否指向同一个对象 不知道它的类型?
  2. 我的问题有更优雅的解决方案吗?

我是 C++ 新手,所以如果我完全误解了某些内容,请原谅...

如果您的 classes 是多态的(至少有一个虚函数),那么 dynamic_cast<void *>() 将 return 一个指向最派生对象开头的指针 - 所以它将始终 return 相同对象的相同答案,即使您从指向不相关基数的指针开始 classes.

但是,如果您已经将指针转换为 void *,那就太晚了。您最好只存储指向某些公共基础的指针 class.

void* 是 C++ 中一个古老的 C 概念,您 知道您正在使用什么类型,因为这是模板编程的基础。为此,让我们将您的函数签名更改为:

template <typename T>
void removeObject(T* object);

从这里我们可以使用is_base_of来识别类型是否是每个vector的元素的基础value_type:

if(is_base_of_v<T, decltype(as)::value_type>) {
    auto aPos = find(cbegin(as), cend(as), *static_cast<A*>(object));

    if(aPos != cend(as)) as.erase(aPos);
}

if(is_base_of_v<T, decltype(bs)::value_type>) {
    auto bPos = find(cbegin(bs), cend(bs), *static_cast<B*>(object));

    if(bPos != cend(bs)) bs.erase(bPos);
}

显然,如果 object 是指向实际基数 class 的指针,那么 static_cast 将是完全非法的。我假设即使 object 是一个指向基数 class 的指针,它确实是 static_cast 的类型,否则我们需要回到绘图板。