【发布时间】:2013-12-14 18:55:21
【问题描述】:
鉴于 constant 访问者和 mutable 访问者之间的区别在于,常量访问者中的方法不允许修改访问的对象。
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机制来合并两者 (例如提供 'const' 作为模板的参数)? - 如何设置这些访问者,以便我可以通过
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 语句的情况。
另一种是从数据库表中加载字段。
【问题讨论】:
-
“字段”类有什么关系?
-
@Cheersandhth.-Alf 字段类是记录的组成部分,例如在数据库/表记录中。
-
暂时先不管
const的问题,你可以让每个visit函数对应一个特定的接口。访问者只需要实现它处理的接口(这些接口可能以某种分层方式排列以支持类型的层次结构)。被访问的字段对象然后可以dynamic_cast访问者下到它自己的基本类型对应的接口,如果有这样的接口,就调用它的函数。这集中了显式向下转换。相比之下,您上面的方案不需要任何向下转换,但具有潜在的维护 prblm -
我记得,Andrei Alexandrescu 在他的《现代 C++ 设计》一书中对各种访问者模式实现进行了很好的概述和权衡分析。 Loki 库可能支持其中的一些。
标签: c++ inheritance visitor-pattern const-correctness