Учитывая, что разница между постоянная посетитель и изменчивый посетитель заключается в том, что методы постоянного посетителя не могут изменять посещаемый объект.
class Integer_Field;
class Boolean_Field;
class Text_Field;
class Visitor_Constant
{
public:
virtual void visit(const Integer_Field& f) = 0;
virtual void visit(const Boolean_Field& f) = 0;
virtual void visit(const Text_Field& f) = 0;
};
class Visitor_Mutable
{
public:
virtual void visit(Integer_Field& f) = 0;
virtual void visit(Boolean_Field& f) = 0;
virtual void visit(Text_Field& f) = 0;
};
Я хотел бы свести к минимуму поддержку этих посетителей. Например, если я придумаю класс Blob_Field
Мне нужно изменить оба класса. Я бы предпочел иметь что-то, где мне нужно изменить только один класс или трафарет.
Проблема обслуживания исчезает, когда есть много классов, определенных от этих родительских посетителей. Это главная причина, по которой я хочу упростить обслуживание.
Мои вопросы:
(Примечание: это должно быть решено без использования функций C ++ 11, так как моя среда разработки не поддерживает C ++ 11, и в настоящее время я не могу обновляться.)
template
механизм слияния двухVisitor_Constant
к методам, использующим Visitor_Mutable
?Примечание. Комбинируя эти классы через родительский класс, удваивает методы посетителя, которые должны быть реализованы и поддерживаться.
Редактировать 1: Классовые отношения
class Component; // Base class for fields and records.
class Field : public Component; // Base class for all fields
class Record : public Component // Base class for all records
{
std::vector< boost::shared_ptr<Component> > component_container;
};
class Integer_Field : public Field;
class Boolean_Field : public Field;
class Text_Field : public Field;
Редактировать 2: Рациональность полей
Одна рациональность для полей, которые обрабатываются специально, — это случай создания оператора SQL для создания таблицы.
Другой — для загрузки полей из таблицы базы данных.
Есть ли способ использовать
template
механизм объединения двух (например, поставка «const» в качестве параметра в шаблон)?
Вы можете предоставить его с помощью параметра шаблона шаблона, а также сделать реализацию чистых посетителей универсальной. Первоначально я делал это в C ++ 11, но так как вы говорите, что у вас его нет, я представлю один со списками типов.
Вот реализация списка типов.
/* Our empty node for our type list. */
class Empty {};
/* Cons for our type list. */
template <typename First_, typename Rest_>
class Cons {
public:
/* First type */
typedef First_ First;
/* Rest. */
typedef Rest_ Rest;
}; // Cons<First_, Rest_>
Вот общая реализация посетителя.
/* Forward declaration. */
template <template <typename> class Decorator, typename Members>
class VisitorRecur;
/* Base case. */
template <template <typename> class Decorator, typename Member>
class VisitorRecur<Decorator, Cons<Member, Empty> > {
public:
/* Pure virtual for each of the members. */
virtual void operator()(
typename Decorator<Member>::Type that) const = 0;
}; // VisitorRecur<Decorator, Member>
/* Recursive case. */
template <template <typename> class Decorator, typename Members>
class VisitorRecur
: public VisitorRecur<Decorator, typename Members::Rest> {
public:
/* Bring the operator()s into scope. */
using VisitorRecur<Decorator, typename Members::Rest>::operator();
/* Pure virtual for each of the members. */
virtual void operator()(
typename Decorator<typename Members::First>::Type that) const = 0;
}; // VisitorRecur<Decorator, typename Members::Rest>
/* Final visitor. */
template <template <typename> class Decorator, typename Members>
class Visitor : public VisitorRecur<Decorator, Members> {
public:
/* Bring the operator()s into scope. */
using VisitorRecur<Decorator, Members>::operator();
}; // Visitor<Decorator, Members>
Вот два декоратора, которые мы определим.
/* ConstRef. */
template <typename T>
class ConstRef {
public:
typedef const T & Type;
}; // ConstRef<T>
/* Ref. */
template <typename T>
class Ref {
public:
typedef T & Type;
}; // Ref<T>
Вот пример использования для этого.
/* Forward declarations. */
class Circle;
class Square;
class Triangle;
/* Add the members into a type list. */
typedef Cons<Circle, Cons<Square, Cons<Triangle, Empty> > > Members;
/* Our const visitor which accepts the members by const-ref. */
typedef Visitor<ConstRef, Members> ConstVisitor;
/* Our mutating visitor which accepts the members by ref. */
typedef Visitor<Ref, Members> MutatingVisitor;
Других решений пока нет …