从对超类的引用确定对象标识

时间:2009-08-20 17:01:47

标签: c++

我有以下一对功能:

void RegisterSink( ISink & Sink )
void UnregisterSink( ISink & Sink )

ISink是一个抽象基类。在内部,我想在std :: set中存储指向接收器的指针。当一个接收器未注册时,我只需在我的集合中搜索指针,然后将其删除。我的问题是,有没有办法,采用参数Sink的地址会产生不同的结果,尽管同一个对象作为参数传递。我知道,当在某些多继承szenarios中进行转换时,指针会发生变化,但这种情况又如何呢?

提前致谢!

3 个答案:

答案 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中的虚拟对象)