2012-02-15 4 views
7

Tengo punteros Base * para dos instancias de tipo polimórfico y necesito determinar si los objetos a los que se hace referencia son equivalentes.¿Existe un enfoque idiomático en C++ para comparar tipos polimórficos para la equivalencia de objetos?

Mi enfoque actual es utilizar por primera vez RTTI para verificar la igualdad de tipos. Si los tipos son iguales, entonces llamo a una función virtual is_equivalent.

¿Hay un enfoque más idiomático?

+1

¿Cuáles son los objetos equivalentes según usted? –

+0

Para la mayoría de las clases derivadas, el equivalente simplemente significa que el miembro variables todo el mismo valor. – RandomBits

+0

Esta pregunta podría estar relacionada: http://stackoverflow.com/questions/1691007/whats-the-right-way-to-overload-operator-for-a-class-hierarchy –

Respuesta

6

Para la mayoría de las clases derivadas, lo que equivale simplemente significa que las variables miembro todos el mismo valor

En C++ esto se llama 'igualdad' y por lo general se implementa utilizando operator==(). En C++ se puede anular el significado de los operadores, es posible escribir:

MyType A; 
MyType B; 
if (A == B) { 
    // do stuff 
} 

Y tienen == llamada a una función personalizada que defina.

Creo que desea diferenciar la igualdad de la identidad que significaría el mismo objeto (es decir, la misma dirección).

que se pueden implementar como función miembro o función libre (de Wikipedia):

bool T::operator ==(const T& b) const; 
bool operator ==(const T& a, const T& b); 

En su caso se desea implementar operator== de la clase base, y luego realizar lo que está haciendo.

Más concretamente sería el siguiente aspecto:

class MyBase 
{ 
    virtual ~MyBase(); // reminder on virtual destructor for RTTI 
    // ... 
private: 
    virtual bool is_equal(const MyBase& other); 

    friend bool operator ==(const MyBase& a, const MyBase& b); 

    // ...  
}; 

bool operator ==(const MyBase& a, const MyBase& b) 
{ 
    // RTTI check 
    if (typeid(a) != typeid(b)) 
     return false; 
    // Invoke is_equal on derived types 
    return a.is_equal(b); 
} 


class D1 : MyBase 
{ 
    virtual bool is_equal(const Base& other) 
    { 
     const D1& other_derived = dynamic_cast<const D1&>(other); 
     // Now compare *this to other_derived 
    } 
}; 

class D2 : MyBase; 
{ }; 


D1 d1; D2 d2; 
bool equal = d1 == d2; // will call your operator and return false since 
         // RTTI will say the types are different 
+0

En la función 'operator ==', me gustaría llamar a una función virtual para comparar los dos objetos. Si la firma de la función de comparación fuera algo así como 'virtual bool is_equal (MyBase const &)'. Esto parece funcionar, pero requiere un downcast explícito en la implementación de 'is_equal' para obtener el tipo de objeto derivado. – RandomBits

+0

Sí, debería ser la firma. (Disculpe, edite) Sí, requiere un elenco. Puede especificar que se llame a 'is_equal' con un objeto del mismo tipo, que sea privado para que solo' == 'pueda llamarlo (en ese caso, debe declarar a su operador como amigo). –

+0

Olvidó la parte "amigo" en su edición y un 'virtual'. Lo he agregado (pero no probado). –

Cuestiones relacionadas