<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Visitor vs dynamic_cast]]></title><description><![CDATA[<p>Es geht darum mathe Ausdrücke zu parsen und dann umzuformen. Welche Umformungen benötig werden steht nicht fest, allerdings ist bekannt welche Operationen in einem Ausdruck vorkommen dürfen.</p>
<p>Meine Ansatz war das ganze in einen Parsebaum zu laden und diesen zu bearbeiten. In etwa wie folgendermaßen:</p>
<pre><code class="language-cpp">class ExprBase{};
class Sum:public ExprBase{ExprBase*a,b};
class Product:public ExprBase{ExprBase*a,b};
class XEvoc:public ExprBase{};
class Num:public ExprBase{int num};
</code></pre>
<p>So nun stellt sich die Frage wie ich den Parsebaum anfassen soll. Nach einiger Suche im Internet kam ich auf folgenden <a href="http://www.informatik.fh-muenchen.de/~schieder/seminar-oo-modellieren-ws97-98/f7alpha1.informatik.fh-muenchen.de/~ifw93027/visitor.html" rel="nofollow">Link</a>. Ich hab dies auf diese Weise implementiert allerdigns war alles anderes als zufrieden mit der Lösung. Der Code der zum Beispiel nötig war um einfach heraus zu finden ob ein Ausdruck von x abhängt oder nicht war einfach erschlagend. Das ständige herumgeschlage mit Visitorobjekten war auch lässtig und erschien mir alles anders als intutive.</p>
<pre><code class="language-cpp">struct DependsOnX:public Visitor{
  DependsOnX(){result = false;}
  void visit(Product*){a-&gt;visit_by(this); b-&gt;visit_by(this);}
  void visit(Sum*){a-&gt;visit_by(this); b-&gt;visit_by(this);}
  void visit(Number*){}
  void visit(XEvoc*){result = true;}
  bool result;
};
//...
DependsOnX vistor;
expr-&gt;visit_by(visitor);
if(visitor.result){...}
</code></pre>
<p>Ich hab mich danach entschieden ganz einfach dynamic_cast und eine if else Kaskade zu nehmen. Erstaunlicherweise ging dies recht gut und bis auf das lässtige Gecasts auch ansonsten recht intuive. Desweiteren entfällt die ganze Visitor Hierarchie was das ganz auch einfacher macht. Es wurde sogar möglich eine Hierarchie zwischen den Operationen auszunutzen.</p>
<pre><code class="language-cpp">class ExprBase{};
class BinOp:ExprBase{ExprBase*a,*b};
class Sum:public BinOp{};
class Product:public BinOp{};
class XEvoc:public ExprBase{};
class Num:public ExprBase{int num};

bool depends_on_x(ExprBase*expr){
  if(BinOp*op = dynamic_cast&lt;BinOp*&gt;(expr))
    // Folgende Zeile wäre beim Visitorpattern doppelt vorhanden.
    return depends_on_x(op-&gt;a) || depends_on_x(op-&gt;b); 
  else if(dynamic_cast&lt;XEvoc*&gt;(expr))
    return true;
  return false;
}
//...
if(depends_on_x(expr)){...}
</code></pre>
<p>Nachdem ich mir ein wenig des Kopf über das Visitorpattern gemacht habe bin ich zum Schluss gekommen, dass es keine Vorteile gegenüber dynamic_cast hat sogar ein paar kleine Nachteile.</p>
<p>Hab ich den Zweck dieses Pattern nicht verstanden?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/135738/visitor-vs-dynamic_cast</link><generator>RSS for Node</generator><lastBuildDate>Sat, 29 Aug 2026 02:39:20 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/135738.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 04 Feb 2006 15:49:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Visitor vs dynamic_cast on Sat, 04 Feb 2006 15:49:07 GMT]]></title><description><![CDATA[<p>Es geht darum mathe Ausdrücke zu parsen und dann umzuformen. Welche Umformungen benötig werden steht nicht fest, allerdings ist bekannt welche Operationen in einem Ausdruck vorkommen dürfen.</p>
<p>Meine Ansatz war das ganze in einen Parsebaum zu laden und diesen zu bearbeiten. In etwa wie folgendermaßen:</p>
<pre><code class="language-cpp">class ExprBase{};
class Sum:public ExprBase{ExprBase*a,b};
class Product:public ExprBase{ExprBase*a,b};
class XEvoc:public ExprBase{};
class Num:public ExprBase{int num};
</code></pre>
<p>So nun stellt sich die Frage wie ich den Parsebaum anfassen soll. Nach einiger Suche im Internet kam ich auf folgenden <a href="http://www.informatik.fh-muenchen.de/~schieder/seminar-oo-modellieren-ws97-98/f7alpha1.informatik.fh-muenchen.de/~ifw93027/visitor.html" rel="nofollow">Link</a>. Ich hab dies auf diese Weise implementiert allerdigns war alles anderes als zufrieden mit der Lösung. Der Code der zum Beispiel nötig war um einfach heraus zu finden ob ein Ausdruck von x abhängt oder nicht war einfach erschlagend. Das ständige herumgeschlage mit Visitorobjekten war auch lässtig und erschien mir alles anders als intutive.</p>
<pre><code class="language-cpp">struct DependsOnX:public Visitor{
  DependsOnX(){result = false;}
  void visit(Product*){a-&gt;visit_by(this); b-&gt;visit_by(this);}
  void visit(Sum*){a-&gt;visit_by(this); b-&gt;visit_by(this);}
  void visit(Number*){}
  void visit(XEvoc*){result = true;}
  bool result;
};
//...
DependsOnX vistor;
expr-&gt;visit_by(visitor);
if(visitor.result){...}
</code></pre>
<p>Ich hab mich danach entschieden ganz einfach dynamic_cast und eine if else Kaskade zu nehmen. Erstaunlicherweise ging dies recht gut und bis auf das lässtige Gecasts auch ansonsten recht intuive. Desweiteren entfällt die ganze Visitor Hierarchie was das ganz auch einfacher macht. Es wurde sogar möglich eine Hierarchie zwischen den Operationen auszunutzen.</p>
<pre><code class="language-cpp">class ExprBase{};
class BinOp:ExprBase{ExprBase*a,*b};
class Sum:public BinOp{};
class Product:public BinOp{};
class XEvoc:public ExprBase{};
class Num:public ExprBase{int num};

bool depends_on_x(ExprBase*expr){
  if(BinOp*op = dynamic_cast&lt;BinOp*&gt;(expr))
    // Folgende Zeile wäre beim Visitorpattern doppelt vorhanden.
    return depends_on_x(op-&gt;a) || depends_on_x(op-&gt;b); 
  else if(dynamic_cast&lt;XEvoc*&gt;(expr))
    return true;
  return false;
}
//...
if(depends_on_x(expr)){...}
</code></pre>
<p>Nachdem ich mir ein wenig des Kopf über das Visitorpattern gemacht habe bin ich zum Schluss gekommen, dass es keine Vorteile gegenüber dynamic_cast hat sogar ein paar kleine Nachteile.</p>
<p>Hab ich den Zweck dieses Pattern nicht verstanden?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/985806</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/985806</guid><dc:creator><![CDATA[Irgendwer]]></dc:creator><pubDate>Sat, 04 Feb 2006 15:49:07 GMT</pubDate></item><item><title><![CDATA[Reply to Visitor vs dynamic_cast on Sat, 04 Feb 2006 17:07:40 GMT]]></title><description><![CDATA[<p>Hallo,<br />
Visitor lohnt sich hauptsächlich, wenn die Hierarchie (die besucht wird) stabil bleibt (also keine weiteren Klassen), aber ständig neue Funktionen hinzukommen. In diesem Fall wird die neue Funktionalität in die Besucher-Hierarchie ausgelagert (jeweils repräsentiert durch eine neue Klasse). Du schreibst also neuen Code, statt alten zu duplizieren. Ohne Visitor müsstest du deine if-else-Kaskaden ständig wiederholen (für jede neue Funktion), was die Wartung erschwert, da du nun x-Mal mehr oder weniger den selben Code akutell halten musst.</p>
<p>Btw: Hast du dir mal das Interpreter-Pattern angeschaut?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/985909</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/985909</guid><dc:creator><![CDATA[HumeSikkins]]></dc:creator><pubDate>Sat, 04 Feb 2006 17:07:40 GMT</pubDate></item></channel></rss>