我有以下一对功能:
void RegisterSink( ISink & Sink )
void UnregisterSink( ISink & Sink )
ISink是一个抽象基类。在内部,我想在std :: set中存储指向接收器的指针。当一个接收器未注册时,我只需在我的集合中搜索指针,然后将其删除。我的问题是,有没有办法,采用参数Sink的地址会产生不同的结果,尽管同一个对象作为参数传递。我知道,当在某些多继承szenarios中进行转换时,指针会发生变化,但这种情况又如何呢?
提前致谢!
答案 0 :(得分:8)
正如您所说,在具有多重继承的虚拟类之间进行转换时,指针地址可能会发生变化。但是,在您的情况下,静态类型始终是相同的:ISink
因此,保证此静态类型的两个点是安全的,并且可以产生可重现的结果。
答案 1 :(得分:2)
在多次继承的情况下进行偏移调整。 IFAIK,他们必须指向比较相等和可排序的指针与std :: less<>例如,如果您的对象从ISink继承多次,而ISink在所有情况下都不是虚拟基类。
答案 2 :(得分:1)
在多重继承的情况下,“同一对象”的含义有时并不明显。 例如,如果ISink在基类列表中出现两次并且未使用“virtual”继承,则可能出现这种情况:
class A {};
class B:public A {};
class C:public A {};
class D:public B,public C {};
...
void f(A *a);
...
{
D d;
f(static_cast<B*>(&d));
f(static_cast<C*>(&d));
}
在这种情况下,f将获得两个不同的地址。 是否相同的对象可能取决于上下文。 如果你想把它们视为同一个对象,那么dynamic_casting to void *可能会有所帮助 - 它会成为大多数派生类(当然需要A中的虚拟对象)