Oppen's algorithmをC++で実装しようとしています。C++ Visitorパターンとスマートポインタ
このアルゴリズム(印刷とスキャン)の基本ルーチンは、トークンタイプでディスパッチします。 訪問者パターンを使用してこのディスパッチを実装するのは当然のようです。 問題は、ルーチンがネストされており、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) /* .. */);
/* ... */
}
/* .. */
}
あなたが見ることができるように、オープン・トークンは、任意のデータを運ばないと、容易な場所に構築することができます。 Textトークンはデータ(std :: string)を持ち、ストリームにプッシュするためにコピーする必要があります。 ストリームは、OpenおよびTextという共通の抽象基本クラスのためにポインタで構成する必要があります。
外部には、そのテキストトークンへのスマートポインタがあるので、私はコピーを避け、単に既存のスマートポインタを使用したいと思います。 ただし、acceptメソッドはそのスマートポインタにアクセスできません。
スマートポインタにビジターパターンを直接実装する方法はありますか?そうでない場合、どのようにしてテキストトークンのコピーコストを削減できますか?
'Visitor'のあなたの定義は何ですか? (また、あなたがそれが問題であることを示すためにプロファイリングするまで、私はコピーについてあまり心配しないでしょう)。 –
私は実装を追加しました。古典的なビジターパターン、AFAIK。そして、ええ、最適化はそれに値するものではないかもしれませんが、そうであれば、それを正しく行う方法はまだ分かりません。だから私は尋ねます;) – choeger
"外側には、そのテキストトークンへのスマートなポインタがあります。" *トークンの各*を 'shared_ptr'に保存していますか?つまり、(基本クラスへの)共有ポインタの範囲がありますか?あなたはそれらのすべてに訪問者を渡しますか? –