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 ++, чтобы понять, почему.