考虑两个指针如何检查两个指针是否指向同一个对象?
A* a;
B* b;
A和B是多态的类。 如何检查a和b是否指向同一个对象?
更准确地说,我们指定a和b指向同一个对象,如果存在类型d的一些对象d,使得两个*和* b是d的类层次结构的某个地方。
我建议如下解决方案:
dynamic_cast<void*>(a) == dynamic_cast<void*>(b)
实际上,根据该标准,
dynamic_cast<void*>(v)
产量“的指针最派生对象用V指向(n3242.pdf。 :§5.2.7 - 7)。 如果两者的派生最相同的对象,那么指针指向同一个对象。
我很确定它应该始终从实际的角度正确工作。但理论上,乍看之下,所提出的平等似乎会产生误判,例如,如果b指向A的第一个成员(而不是A的祖先)。虽然A和它的成员实际上不可能获得相同的地址,因为A的虚拟表指针应该位于该成员之前,但该标准并没有强制虚拟表并且没有提及类布局。
所以,我的问题是:
是所提出的解决方案,从标准的角度看是否正确?
有没有关于私人(受保护)继承或cv资格的警告?
有没有更好的解决方案?
[编辑]
我试图提出一些例子示出了相对复杂的场景。在这种情况下,动态交叉转换和静态转换是不明确的。
// proposed impplementation:
template<typename P, typename Q>
bool test_ptrs(const P* p, const Q* q)
{
return (dynamic_cast<const void*>(p) == dynamic_cast<const void*>(q));
}
struct Root
{
virtual ~Root(){};
};
struct A: public Root // nonvirtually
{
};
struct B: public Root // nonvirtually
{
};
struct C: public A, B // nonvirtual diamond started with Root
{
Root another_root_instance;
};
int main()
{
C c;
A* pa= &c;
B* pb= &c;
bool b = (dynamic_cast<void*>(pa) == dynamic_cast<void*>(pb));
Root* pra= dynamic_cast<Root*> (pa);
Root* prb= dynamic_cast<Root*> (pb);
//Root* prc= dynamic_cast<Root*> (&c); // runtime error, ambiguous cast
Root* prr= dynamic_cast<Root*>(pra);
Root* pcar= dynamic_cast<Root*>(pra);
Root* pcbr= dynamic_cast<Root*>(prb);
if(
test_ptrs(pa, pb)
&& test_ptrs(pra, prb)
&& !test_ptrs(pa,&c.another_root_instance)
)
{
printf("\n test passed \n");
}
}
为什么不'a == b'? – iammilind 2012-04-02 10:24:00
@iammilind:A和B可能是一些D的基类,但彼此无关 – user396672 2012-04-02 10:27:02
@iammilind的+1 - 旧的'uns是最好的! – 2012-04-02 10:27:15