我有两个std::vector
指向类A
和B
的指针,我正在尝试创建一个从这些向量中移除对象的方法。此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 comparison和C++ pointer multi-inheritance fun之后,我理解了原因,但在这两种情况下,建议的解决方案是将指针转换为*subclass
。我的问题是:
我是C ++的新手所以请原谅我,如果我彻底误解了某些东西......
答案 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
的类型,否则我们需要回到绘图板。