considerar dos punteroscómo comprobar si dos punteros apuntan al mismo objeto o no?
A* a;
B* b;
Tanto A como B son clases polimórficas. ¿Cómo verificar si a y b apuntan al mismo objeto o no?
Más precisamente, especifiquemos un punto a y un punto para el mismo objeto si existe algún objeto d de tipo D tal que tanto * a como * b están en algún lugar de la jerarquía de clases de d.
propondría la siguiente solución:
dynamic_cast<void*>(a) == dynamic_cast<void*>(b)
De hecho, según la norma,
dynamic_cast<void*>(v)
rendimientos “un puntero al objeto más derivada apuntada por v (n3242.pdf. : § 5.2.7 - 7). Si el más derivado para ambos es el mismo objeto, los punteros apuntan al mismo objeto.
Estoy bastante seguro de que siempre debería funcionar correctamente desde el punto de vista práctico. Pero teóricamente, a primera vista, la igualdad propuesta parece producir falsos positivos, por ejemplo, en caso de que b señale al primer miembro de A (no al antepasado de A). Aunque es prácticamente imposible obtener direcciones iguales para A y su miembro, ya que el puntero de tabla virtual de A debe ubicarse antes que este miembro, el estándar no ordena tablas virtuales y no dice nada sobre el diseño de clase.
Por lo tanto, mis preguntas son:
es la solución propuesta correcta desde el punto de vista estándar?
¿Existen advertencias sobre herencia privada (protegida) o cv-qualification?
¿Hay mejores soluciones?
[EDIT]
I tratado de presentar algún ejemplo que ilustra un escenario relativamente complejo. En este caso, el crosscasting dinámico y el fundido estático son ambiguos.
// 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");
}
}
¿Por qué no 'a == b'? – iammilind
@iammilind: A y B pueden ser clases base para algunos D pero no relacionados entre sí – user396672
+1 para @iammilind: ¡los viejos son los mejores! –