<?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[Klassendesign für die grafische Darstellung]]></title><description><![CDATA[<p>Hallo da!<br />
Um mal einen Kontext für mein Problem zu geben: Ich bastel mir gerade einen grafischen Editor für gerichtete Graphen zusammen. Da mit der Problemstellung einher geht, dass alles auf Events basiert und der Benutzer mit bestimmten visuellen Repräsentationen von den unterliegenden Daten hantiert, habe ich mir eine Schnittstelle zusammengebastelt, die das ganze Neu-Zeichnen und die benutzereingaben an die einzelnen Objekte weiterleitet.</p>
<p>Das mündete dann in eine Schnittstelle für alle grafischen Objekte:</p>
<pre><code class="language-cpp">class visual_object {
    virtual void mouseClick( ... );
    virtual void bbox( rect&amp; );
    virtual void changed_bbox( rect&amp; );
    virutal void draw( ... );

    virtual event get_prechange_event() const;
    virtual event get_changed_event() const;

    ....
};
</code></pre>
<p>Das ganze delegiert also passend etwaige Events &quot;nach unten&quot; und der View hört den Objekten im Gegenzug zu, ob sie sich verändern und versucht das Neuzeichen dann einigermaßen effizient zu gestalten. So weit so gut. Von dieser Klasse habe ich dann einiges abgelitten unter anderem natürlich auch:</p>
<pre><code class="language-cpp">class visual_node : public visual_object;
class visual_edge : public visual_object;
</code></pre>
<p>Bisher hatte ich nicht vorgesehen, dass visual_object Kinder haben können (also Teil einer Hierarchie). Nun hatte ich aber den Gedanken, dass in einem gerichteten Graphen eigentlich der Quellenknoten einer Kante für diese Kante zuständig sein sollte. Also machte ich mich erstmal daran, einer Container-Klasse zu basteln, die alle Events &quot;von oben und unten&quot; (in der Hierarchie) entsprechend weiterleitet, was auch super funktioniert.</p>
<pre><code class="language-cpp">class visual_container : public visual_object {
public:
     addChild( boost::shared_ptr&lt;visual_object&gt; child );
     ...
};
</code></pre>
<p>Funktionierte einigermaßen gut, ich konnte direkt aus der Viewklasse einiges rausnehmen und dort sozusagen nur noch ein &quot;Desktop&quot;-Objekt (Also eine Wurzel) speichern und direkt alle events einfach in mein Format konvertieren und dann delegieren.<br />
Aber nachdem ich das getan habe, ist mir aufgefallen, dass ich mein Problem damit überhaupt nicht gelöst hatte. Denn soetwas wie</p>
<pre><code class="language-cpp">class visual_node : public visual_container {
};
</code></pre>
<p>funktioniert jetzt nicht, da visual_node dann seines Teils eigentlich gar kein eigentständiges visual_object mehr ist.<br />
Im Prinzip müsste der Knoten jetzt eigentlich (zumindest meinem Design entsprechend) eher ein Kind von dem visual_container sein, damit das mit dem Event-Routing einigermaßen klappt, aber dann wäre er wiederum nicht mehr &quot;zuständig&quot; für die visual_edge's.<br />
Also im Prinzip bräuchte ich eine Möglichkeit, wie der visual_container Aufrufe an die visual_object-Schnittstelle abfangen kann und nur unter bestimmten Umständen an die Implementation der Schnittstelle von dem visual_node (der in diesem Fall wie oben beschrieben von visual_container abgeleitet ist) weiterleitet.<br />
Die einzige Lösung, die mir da adhoc einfällt, wäre, dass der visual_container das visual_object-Interface unter anderem Namen repliziert und der visual_node dann dieses Interface implementiert. Aber das gefällt mir einfach nicht, weil es dann einen Unterschied für die Implementierung der einzelnen Klassen macht, ob sie Kinder haben können oder nicht.<br />
Andererseits könnte ich einfach jede Klasse von visual_container ableiten, aber ich habe dann Angst dass mir das in weiteren Fällen des gleichen Problems dann genauso geht und ich am Ende ein riesiges Interface für jedes Objekt habe.</p>
<p>Ich hoffe es findet sich jemand, der sich die Zeit nimmt, diese Textwand zu überfliegen und mir evtl. hilfreiche Ratschläge geben kann, ob und wie man das besser lösen könnte. Vielen Dank schon einmal für eure Zeit.</p>
<p>MfG<br />
Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/228971/klassendesign-für-die-grafische-darstellung</link><generator>RSS for Node</generator><lastBuildDate>Mon, 28 Sep 2026 06:35:03 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/228971.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 05 Dec 2008 08:07:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Klassendesign für die grafische Darstellung on Fri, 05 Dec 2008 08:07:28 GMT]]></title><description><![CDATA[<p>Hallo da!<br />
Um mal einen Kontext für mein Problem zu geben: Ich bastel mir gerade einen grafischen Editor für gerichtete Graphen zusammen. Da mit der Problemstellung einher geht, dass alles auf Events basiert und der Benutzer mit bestimmten visuellen Repräsentationen von den unterliegenden Daten hantiert, habe ich mir eine Schnittstelle zusammengebastelt, die das ganze Neu-Zeichnen und die benutzereingaben an die einzelnen Objekte weiterleitet.</p>
<p>Das mündete dann in eine Schnittstelle für alle grafischen Objekte:</p>
<pre><code class="language-cpp">class visual_object {
    virtual void mouseClick( ... );
    virtual void bbox( rect&amp; );
    virtual void changed_bbox( rect&amp; );
    virutal void draw( ... );

    virtual event get_prechange_event() const;
    virtual event get_changed_event() const;

    ....
};
</code></pre>
<p>Das ganze delegiert also passend etwaige Events &quot;nach unten&quot; und der View hört den Objekten im Gegenzug zu, ob sie sich verändern und versucht das Neuzeichen dann einigermaßen effizient zu gestalten. So weit so gut. Von dieser Klasse habe ich dann einiges abgelitten unter anderem natürlich auch:</p>
<pre><code class="language-cpp">class visual_node : public visual_object;
class visual_edge : public visual_object;
</code></pre>
<p>Bisher hatte ich nicht vorgesehen, dass visual_object Kinder haben können (also Teil einer Hierarchie). Nun hatte ich aber den Gedanken, dass in einem gerichteten Graphen eigentlich der Quellenknoten einer Kante für diese Kante zuständig sein sollte. Also machte ich mich erstmal daran, einer Container-Klasse zu basteln, die alle Events &quot;von oben und unten&quot; (in der Hierarchie) entsprechend weiterleitet, was auch super funktioniert.</p>
<pre><code class="language-cpp">class visual_container : public visual_object {
public:
     addChild( boost::shared_ptr&lt;visual_object&gt; child );
     ...
};
</code></pre>
<p>Funktionierte einigermaßen gut, ich konnte direkt aus der Viewklasse einiges rausnehmen und dort sozusagen nur noch ein &quot;Desktop&quot;-Objekt (Also eine Wurzel) speichern und direkt alle events einfach in mein Format konvertieren und dann delegieren.<br />
Aber nachdem ich das getan habe, ist mir aufgefallen, dass ich mein Problem damit überhaupt nicht gelöst hatte. Denn soetwas wie</p>
<pre><code class="language-cpp">class visual_node : public visual_container {
};
</code></pre>
<p>funktioniert jetzt nicht, da visual_node dann seines Teils eigentlich gar kein eigentständiges visual_object mehr ist.<br />
Im Prinzip müsste der Knoten jetzt eigentlich (zumindest meinem Design entsprechend) eher ein Kind von dem visual_container sein, damit das mit dem Event-Routing einigermaßen klappt, aber dann wäre er wiederum nicht mehr &quot;zuständig&quot; für die visual_edge's.<br />
Also im Prinzip bräuchte ich eine Möglichkeit, wie der visual_container Aufrufe an die visual_object-Schnittstelle abfangen kann und nur unter bestimmten Umständen an die Implementation der Schnittstelle von dem visual_node (der in diesem Fall wie oben beschrieben von visual_container abgeleitet ist) weiterleitet.<br />
Die einzige Lösung, die mir da adhoc einfällt, wäre, dass der visual_container das visual_object-Interface unter anderem Namen repliziert und der visual_node dann dieses Interface implementiert. Aber das gefällt mir einfach nicht, weil es dann einen Unterschied für die Implementierung der einzelnen Klassen macht, ob sie Kinder haben können oder nicht.<br />
Andererseits könnte ich einfach jede Klasse von visual_container ableiten, aber ich habe dann Angst dass mir das in weiteren Fällen des gleichen Problems dann genauso geht und ich am Ende ein riesiges Interface für jedes Objekt habe.</p>
<p>Ich hoffe es findet sich jemand, der sich die Zeit nimmt, diese Textwand zu überfliegen und mir evtl. hilfreiche Ratschläge geben kann, ob und wie man das besser lösen könnte. Vielen Dank schon einmal für eure Zeit.</p>
<p>MfG<br />
Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1625785</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1625785</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Fri, 05 Dec 2008 08:07:28 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign für die grafische Darstellung on Sat, 06 Dec 2008 14:04:40 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ohne jetzt sehr detailliert in Dein Klassendesign und die damit verbundenen Probleme einsteigen zu wollen: schau Dir bitte einmal das <strong>Kompositum-Entwurfsmuster</strong> an: <a href="http://de.wikipedia.org/wiki/Kompositum_(Entwurfsmuster)" rel="nofollow">http://de.wikipedia.org/wiki/Kompositum_(Entwurfsmuster)</a></p>
<p>Gruß<br />
Stephan</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1626164</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1626164</guid><dc:creator><![CDATA[red.steve]]></dc:creator><pubDate>Sat, 06 Dec 2008 14:04:40 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign für die grafische Darstellung on Sat, 06 Dec 2008 18:59:45 GMT]]></title><description><![CDATA[<p>Jau, der visual_container stellt ja eben genau so ein Kompositum dar.<br />
Mein Problem fing ja erst an, als ich sozusagen auch ein leaf-Funktionalität in das Kompositum einbauen wollte, damit sich ein Objekt (halt abgeleitet von visual_container) direkt seiner Kinder bewusst ist. Ich habe jetzt im Kompositum die Schnittstelle dupliziert (unter anderem &quot;Namen&quot;) und solch ein Kompositum packt sich nun selbst immer ein Proxy-Objekt in die Kinder-Liste, welches alle Aufrufe an das normale Interface umleitet an das 2.-Interface vom Kompositum, welches dann an die abgeleitete Klasse weiterleitet.<br />
Das gewinnt nun echt keine Schönheitspreise, aber immerhin funktioniert es und ich kam zu der Erleuchtung, dass ein vernünftiges Eventsystem (Außer Punkt-zu-Punkt) nicht wirklich auf einer C++ Klassenhierarchie aufgebaut werden kann. Das nächste Mal lasse ich mir was vernünftiges einfallen.<br />
Danke!</p>
<p>Michael</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1626249</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1626249</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Sat, 06 Dec 2008 18:59:45 GMT</pubDate></item></channel></rss>