【发布时间】:2016-09-29 08:38:32
【问题描述】:
我正在尝试在 C++ 中实现 Oppen's algorithm。
此算法(打印和扫描)中的基本例程在令牌类型上分派。 使用访问者模式来实现这种调度似乎很自然。 问题是:例程是嵌套的,并且 print() 的参数在 scan() 期间被排入堆栈。 为了避免任何内存问题,我想对任务使用智能指针。
所以我的实现看起来像这样:
class Text;
class Line;
class Open;
class Close;
class Visitor {
/* Define virtual visit functions for concrete doc nodes:
*/
public:
virtual void visit(const Text&) = 0;
virtual void visit(const Line&) = 0;
virtual void visit(const Open&) = 0;
virtual void visit(const Close&) = 0;
};
class DocToken
{
protected:
explicit DocToken() {}
friend class Visitor;
public:
virtual void accept(Visitor * visitor) const = 0;
};
class Text : public DocToken {
public:
Text(std::string s) : text(s) {}
void accept(Visitor *visitor) const {
visitor -> visit (*this);
}
std::string text;
};
class Open : public DocToken { /* .. */ }
/* .. */
class Scan : public Visitor {
stream_t stream;
/* ... */
public:
void visit(const Open& x) {
/* ... */
stream.push_back(/* .. */ new Open() /* .. */);
/* ... */
}
void visit(const Text& x) {
/* ... */
stream.push_back(/* .. */ new Text(x) /* .. */);
/* ... */
}
/* .. */
}
如您所见,Open 令牌不携带任何数据,并且可以轻松构建。 Text 标记确实携带数据(std::string)并且必须被复制才能被推送到流中。 由于 Open 和 Text 的通用抽象基类,流需要由指针组成。
由于在外部,有一个指向该文本标记的智能指针,我想避免复制并简单地使用现有的智能指针。 但是,accept 方法无权访问该智能指针。
有没有办法直接在智能指针上实现访问者模式?如果没有,如何降低复制文本令牌的成本?
【问题讨论】:
-
你对
Visitor的定义是什么? (另外,在您分析表明这是一个问题之前,我不会太担心复制)。 -
我添加了实现。经典访客模式,AFAIK。是的,优化可能不值得,但如果是,我仍然不知道如何正确地做到这一点。所以我问;)
-
“由于在外部,有一个指向该文本标记的智能指针” 您是否将 每个 标记存储在
shared_ptr中?即,您是否有一系列共享指针(指向基类),并且您将访问者全部传递给它们? -
是的,这就是我目前所做的。
-
在什么情况下会在访问结构时破坏“外部”智能指针?在访问期间保持根目录而不是依次管理每个部分,似乎确实可以解决问题。
标签: c++ smart-pointers visitor-pattern