Реализация посетителя: постоянный и изменчивый посетитель

Учитывая, что разница между постоянная посетитель и изменчивый посетитель заключается в том, что методы постоянного посетителя не могут изменять посещаемый объект.

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, и в настоящее время я не могу обновляться.)

  1. Есть ли способ использовать template механизм слияния двух
    (например, поставьте const в качестве параметра для шаблона)?
  2. Как я могу настроить этих посетителей, чтобы я мог передать
    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 для создания таблицы.
Другой — для загрузки полей из таблицы базы данных.

0

Решение

Есть ли способ использовать 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;
0

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

Других решений пока нет …

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