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

Existe uma maneira mais simples de fazer isso?

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

questionAnswers(6)

yourAnswerToTheQuestion