- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想知道是否有一个好的设计模式或成语来实现以下内容:
You have an existing class that provides only a visitor interface, as follows
class Visitor {
public:
virtual ~Visitor() { }
virtual void visit(Node *n) = 0;
};
class Tree {
public:
void accept(Visitor *v);
};And you want to have an interface that can be used as follows, which should iterate through the tree in the same order that the visitor would have its
visit
function called.for(iterator it(...), ite(...); it != ite; ++it) {
/* process node */
}
问题似乎是当我们只是调用visit
时,我们失去了控制,不能暂时“回到”循环体去执行一个节点的 Action 。这看起来应该经常出现在现实世界的程序中。知道如何解决吗?
最佳答案
在一般情况下,我不认为这是可能的,至少不干净。
至少按照通常的定义,迭代器期望处理同类集合。即,迭代器通常定义如下:
template <class Element>
class iterator // ...
...所以特定的迭代器只能处理一种特定类型的元素。要处理不同的类型,您最多可以创建一个指向基类(指针/引用)的迭代器,并让它处理派生类的对象。
相比之下,编写这样的访问者非常容易:
class MyVisitor {
public:
void VisitOneType(OneType const *element);
void VisitAnotherType(AnotherType const *element);
};
这可以访问 OneType
或 AnotherType
的节点,即使这两者完全无关。基本上,您的 Visitor 类中有一个 Visit
成员函数,用于它能够访问的每种不同类型的类。
从稍微不同的角度来看,迭代器基本上是一种特殊形式的访问者,它只适用于一种类型的对象。您交换了对访问模式的更多控制,以换取失去访问不相关类型对象的能力。
如果你只需要处理一个类型(尽管那个类型可能是一个基类,而被访问的对象是各种派生类型),那么显而易见的方法是建立一个访问对象的“桥梁”类(Tree
节点,在您的示例中),当它的 visit
被调用时,它只是将它正在访问的节点的地址复制到一些支持迭代器的集合中:
template <class T>
class Bridge {
std::vector<T *> nodes;
public:
virtual void visit(T *n) {
nodes.push_back(n);
}
typedef std::vector<T *>::iterator iterator;
iterator begin() { return nodes.begin(); }
iterator end() { return nodes.end(); }
};
使用这将是一个两步过程:首先像访问者通常那样访问节点,然后将感兴趣的节点收集在一起,您可以像访问任何其他提供迭代器的集合一样迭代它们。那时,您的访问模式仅受您在桥中使用的集合提供的迭代器类的限制。
关于c++ - 如何将访问者界面适配为迭代器界面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5507875/
我正在尝试为玩具语言实现一个解析器。 我已经编写了语法,但是当我尝试从 CST 创建 AST 时遇到了问题。 我定义了一个继承自 MyParserVisitor 的类哪里ASTNode是一个虚拟类,我
我想创建子类对象,它会与其他子类对象做出不同的 react (类可以欢迎另一个类,但不是全部)代码原理源自访客设计模式: class A { public : virtual bool isW
我正在玩 boost A* 算法,从在以下位置找到的示例开始:http://www.boost.org/doc/libs/1_37_0/libs/graph/example/astar-cities.
我正在为我的网站构建一个访问者和点击率计数器,当然,访问者每天是一个唯一的 ip,点击率是每次请求页面时! 我已经创建了数据库和系统来插入和更新我保存统计信息的表! 我正在苦苦挣扎的是,如何对日期进行
如何放弃使用 IE6 浏览我的网站? 就像是 : 如果 ie6 => 死 我正在使用 ASP.Net 谢谢 最佳答案 在asp.net中你可以查看Request.Browser在 Session_st
我目前正在编写解析器。解析器生成一个 AST,然后我使用各种遍历来处理它。 AST 是(简化的): type LiteralExpr = { readonly kind: 'literal',
我正在使用 Antlr4 的 C++ 访问者 api 来遍历解析树。但是,我正在努力使其正常运行。也就是说,我不确定如何使用 visitChildren(ParseTree *tree) 调用。 我为
我的问题是理论性的,而不是如何去做。我想知道专家们如何处理我将在下面描述的情况。 我有一个使用 Angular 和 Breeze 的 SPA。身份验证是基于 token 的。我在 Angular 中设
我有一棵树(在图形意义上)表示一棵树(在物理意义上)。树表示为 BGL 邻接列表,其中每个顶点包含半径和位置属性,即,我的图以以下形式定义 struct TreeVertexType { doub
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
是否可以将域限制为仅允许使用特定浏览器的访问者? 我正在构建一个应用程序,到目前为止它只在 Chrome 中进行过测试,所以我只想在 Beta 测试期间允许 Chrome 用户。基本上,我想在进行测试
你好,我正在尝试实现一个 AST Clang 访问者,这是我的代码。 class ExampleVisitor : public RecursiveASTVisitor { private:
我想构建一个访问者(用于 dikstra),并将 initialise_vertex 用作“颜色映射”修饰符。我想根据条件从搜索中排除一些顶点。所以我想在算法的初始部分将一些顶点设置为“黑色”。 cl
我正在尝试编写一个网站,提示每 10,000 名访问者输入一封可以存储在文本文件中的电子邮件。 我设置了一个点击计数器,它将访问者总数输出到一个文本文件中,因此是否可以将脚本设置为类似于 "如果 nu
我正在尝试将 AST 与 ANTLR4 一起使用,并使用以下文件: 生成器.java import org.antlr.v4.runtime.ANTLRInputStream; import org.
在 BGL 中,我不太明白如何在 bfs/dfs 搜索期间访问图中顶点的固有颜色(白色表示未触及,灰色表示已访问,黑色表示已完成)。 有人可以说明如何从 dfs/bfs 访问者中访问顶点的颜色吗?例如
当用户访问您的网站时,如何获取用户的信息? IP地址 苹果地址 用户个人资料名称 操作系统名称 操作系统版本 操作系统注册到(姓名/公司) 计算机名 浏览器名称 浏览器版本 ISP 名称/Intern
我最近开始使用 Amazon S3 为访问者提供图像,因为这会减少服务器负载。现在,出现了一个新问题:今天我查看了我的 AWS 账单。我注意到我有一大笔账单等着我——20 天内总共有 4TB 的 AW
session 劫持 所以我有一个小问题。我正在尝试识别访问者,这很难通过 $_SERVER veriables 来实现,如以下问题所述:Preventing session hijacking .
我有一个带有两个边定义的图,如下所示: isDepartment: [organisation] -> [organisation] hasAccess: [user] -> [organisatio
我是一名优秀的程序员,十分优秀!