C++ 使用多重继承与未知基比较指针 class
C++ comparing pointers using multiple-inheritance with unknown base class
我有两个 std::vector
指向 类 A
和 B
的指针,我正在尝试创建一个从这些向量中删除对象的方法。该对象可以是也可以不是 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
。我的问题是:
- 如何检查两个指针是否指向同一个对象
不知道它的类型?
- 我的问题有更优雅的解决方案吗?
我是 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
的类型,否则我们需要回到绘图板。
我有两个 std::vector
指向 类 A
和 B
的指针,我正在尝试创建一个从这些向量中删除对象的方法。该对象可以是也可以不是 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
。我的问题是:
- 如何检查两个指针是否指向同一个对象 不知道它的类型?
- 我的问题有更优雅的解决方案吗?
我是 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
的类型,否则我们需要回到绘图板。