Листинг 10.9. Мультиметод нового дополнительного класса
class Derived_c: public Base { public:
virtual bool Operator(const Base &R);
};
bool Derived_c: :0perator(const Base &R) { if (typeid(Derived_a) == typeid(R))
{ // правый аргумент типа А; обработка варианта "С-А"
cout << "С-А" << endl;
return true;
"С-В"
else if (typeid(Derived_b) == typeid(R)) { // правый аргумент типа В; обработка варианта
cout << "С-В" << endl;
return true;
typeid(R))
обработка варианта "С-С"
}
else if (typeid(Derived_c) { // правый аргумент типа
cout << "С-С" << endl;
return true;
}
else throw exception ("Error! Incorrect type argument!");
}
Если требуется, чтобы выполнялась обработка объектов типа С методами класт сов А и В, нужно модифицировать их, добавив проверку правого аргумента на совпадение с типом С. Но делать это в обязательном порядке нет необходимости — все определяется конкретной задачей. Таким образом, у нас реализовано семь сочетаний из девяти, в чем можно убедиться, выполнив такой фрагмент программы:
Derived_a A; Derived_b В; Derived_c С; try {
cout << A.Operator(А) << endl
cout << A.Operator(В) << endl
cout << В.Operator(A) << endl
cout << B.Operator(B) << endl
cout << C.Operator(A) << endl
cout << C.Operator(B) << endl
cout << C.Operator(C) << endl
cout << A.Operator(C) << endl; // вызывает исключение
}
catch(exception &e) v
{ cout << e.what()<< endl; }
Последний оператор вызывает исключение, так как сочетание Derived_a — Deri ved_c не реализовано.
Задачу мы решили — реализовали двойное переключение по типу. Однако даже начинающий программист понимает, что у этого решения есть недостатки. Например, задействован механизм RTTI, который не является самым эффективным в С++. Но это не самое важное. Гораздо хуже, что нам при добавлении нового класса приходится модифицировать тексты методов. Представьте, что классов у нас хотя бы 7-8, и методов, соответственно, тоже. То есть в каждом методе требуется выполнять до семи-восьми однотипных проверок. Добавление нового класса может превратиться в кошмар, поэтому поищем другие пути реализации двойной диспетчеризации. |