Шаблон посетителя c ++: почему каждый производный посетитель должен реализовывать Accept ()?

Я видел пару примеров, которые демонстрируют шаблон посетителей.
Во всех них каждый производный посещенный элемент реализует то, что обычно называется методом Accept ().

В иерархии цветов этот метод может выглядеть следующим образом:

void Red::accept(Visitor *v)
{
v->visit(*this);
}

void Blue::accept(Visitor *v)
{
v->visit(*this);
}

Когда Visitor, как и его наследники, имеют методы:

visit(Red red);
visit(Blue blue)

Мой вопрос: почему бы не реализовать это таким же образом только в базовом классе (в этом примере: Color) и полиморфизм сделает эту работу, а именно, правильное посещение будет вызвано, так как, когда объект является Red динамический тип этого является Red так разыменование это приведет к Red что в свою очередь вызовет визит (красный)?

Что мне не хватает?

7

Решение

Полиморфизм наследования (динамическая диспетчеризация) не применяется к аргументам функции. Другими словами, перегруженные функции выбираются по статическому типу передаваемых аргументов. Если реализовано в базовом классе Color, v->visit(*this) всегда будет звонить visit(Color c),

8

Другие решения

Если только accept ты был …

void Color::accept(Visitor* v)
{
v->visit(*this);
}

visit просто вызвали бы с базовым классом. Для того, чтобы позвонить visit с правильным производным классом вам нужен каждый Color реализовать его, чтобы они могли передать правильно набранный thisтак правильный visit перегрузка называется.

1

Насколько я понимаю, в методах базового класса this Указатель относится к типу base, а не к каким-либо производным классам, поэтому он может обращаться только к методам базового класса и передается как тип Color* this, При переходе к методу посещения он будет пытаться запустить visit(Color* color), поскольку полиморфное поведение применимо только к методам самого класса (но не к другим классам).

1
По вопросам рекламы [email protected]