C ++ expedição dupla para Equals ()
Imagine Eu tenho classe base abstrata Shape
, com classes derivadasCircle
eRectangle
.
class Shape {};
class Circle : public Shape {};
class Rectangle : public Shape {};
Preciso determinar se duas formas são iguais, supondo que eu tenha duasShape*
ponteiros. (Isso ocorre porque tenho duas instâncias devector<Shape*>
e quero ver se eles têm as mesmas formas.)
A maneira recomendada de fazer isso édouble dispatch. O que eu vim com isso é isso (bastante simplificado aqui, para que as formas sejam iguais a todas as outras formas do mesmo tipo):
class Shape {
public:
virtual bool equals(Shape* other_shape) = 0;
protected:
virtual bool is_equal(Circle& circle) { return false; };
virtual bool is_equal(Rectangle& rect) { return false; };
friend class Circle; // so Rectangle::equals can access Circle::is_equal
friend class Rectangle; // and vice versa
};
class Circle : public Shape {
public:
virtual bool equals(Shape* other_shape) { return other_shape->is_equal(*this); };
protected:
virtual bool is_equal(Circle& circle) { return true; };
};
class Rectangle : public Shape {
public:
virtual bool equals(Shape* other_shape) { return other_shape->is_equal(*this); };
protected:
virtual bool is_equal(Rectangle& circle) { return true; };
};
Isso funciona, mas preciso adicionar umequals
função efriend
declaração emShape
para cada classe derivada. Então eu tenho que copiar e colar oexact sameequals
function em cada classe derivada também. Este é um monte de clichê para dizer, 10 formas diferente
dynamic_cast
está fora de questão; muito devagar. (Sim, fiz um benchmarking. A velocidade é importante no meu aplicativo.)
Tentei isso, mas não funciona:
class Shape {
public:
virtual bool equals(Shape* other_shape) = 0;
private:
virtual bool is_equal(Shape& circle) { return false; };
};
class Circle : public Shape {
public:
virtual bool equals(Shape* other_shape) { return other_shape->is_equal(*this); };
private:
virtual bool is_equal(Circle& circle) { return true; };
};
class Rectangle : public Shape {
public:
virtual bool equals(Shape* other_shape) { return other_shape->is_equal(*this); };
private:
virtual bool is_equal(Rectangle& circle) { return true; };
};
equals()
sempre retorna falso, mesmo em formas idênticas. Parece que o envio está sempre escolhendo ois_equal(Shape&)
função base, mesmo quando uma correspondência "mais específica" estiver disponível. Provavelmente isso faz sentido, mas eu não entendo o envio de C ++ o suficiente para saber o porqu