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

时间:2016-05-27 17:24:56

标签: c++ pointers multiple-inheritance

我有两个std::vector指向类AB的指针,我正在尝试创建一个从这些向量中移除对象的方法。此Object可能是也可能不是A和/或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 comparisonC++ pointer multi-inheritance fun之后,我理解了原因,但在这两种情况下,建议的解决方案是将指针转换为*subclass。我的问题是:

  1. 如何检查两个指针​​是否指向同一个对象 不知道它的类型?
  2. 我的问题有更优雅的解决方案吗?
  3. 我是C ++的新手所以请原谅我,如果我彻底误解了某些东西......

2 个答案:

答案 0 :(得分:3)

如果你的类是多态的(至少有一个虚函数),那么dynamic_cast<void *>()将返回一个指向最派生对象开头的指针 - 所以它总会为同一个对象返回相同的答案,即使你从指向不相关基类的指针开始。

但是如果你已经将指针转换为void *,那就太晚了。你可能最好只存储指向某个公共基类的指针。

答案 1 :(得分:0)

void*是C ++中的旧C概念,您希望知道您正在使用哪种类型,因为这是模板编程的基础。为此,我们可以将您的功能签名更改为:

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

从这里开始,我们可以使用is_base_of来确定该类型是否是每个vector的{​​{1}}元素的基础:

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); } 是指向实际基类的指针,static_cast将完全违法。我假设虽然object是指向基类的指针,但它实际上是object的类型,否则我们需要回到绘图板。