C ++ Двойная отправка для равных ()

Представь у меняабстрактный базовый класс Shapeс производными классамиCircle а такжеRectangle.

class Shape {};
class Circle : public Shape {};
class Rectangle : public Shape {};

Мне нужно определить, равны ли две фигуры, при условии, что у меня есть двеShape* указатели. (Это потому, что у меня есть два случаяvector<Shape*> и я хочу посмотреть, имеют ли они одинаковые формы.)

Рекомендуемый способ сделать этодвойная отправка, Я придумал вот что (здесь очень упрощено, чтобы формы были равны всем другим фигурам того же типа):

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; };
};

Это работает, но я должен добавить отдельныйequals функция иfriend декларация вShape для каждого производного класса. Затем я должен скопировать и вставитьточно такой жеequals функция в каждый производный класс тоже. Это ужасно много шаблонов, скажем, 10 различных форм!

Есть ли более простой способ сделать это?

dynamic_cast не может быть и речи; слишком медленно. (Да, я проверил это. Скорость имеет значение в моем приложении.)

Я пробовал это, но это не работает:

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() всегда возвращает false, даже на идентичных фигурах. Кажется, отправка всегда выбираетis_equal(Shape&) базовая функция, даже когда доступно «более конкретное» соответствие. Это, вероятно, имеет смысл, но я недостаточно хорошо понимаю диспетчеризацию C ++, чтобы понять, почему.

Ответы на вопрос(6)

Ваш ответ на вопрос