<?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[polymorphe Objekthierachie kapseln]]></title><description><![CDATA[<p>Hallo,<br />
ich versuche mich gerade an einer kleinen GUI-Lib, die (zumindest) auf Linux und Windows das native Zeichnen von Festern u.ä. ermöglichen soll. Ich bediene mich dabei dem &quot;Abstract Factory Pattern&quot;, indem ich für die verschiedene Betriebssysteme jeweils verschiedene &quot;GUI-Factories&quot; implementiere, was dann ungefähr so aussieht:</p>
<pre><code class="language-cpp">// GuiFactory.h
class GuiFactory{
public:
   virtual GuiWindow* CreateWindow() =0;
}

// Win32Factory.h
#include &quot;GuiFactory.h&quot;
#include &quot;Win32Window.h&quot;    
class Win32Factory : public GuiFactory{
public:
   GuiWindow* CreateWindow(){
       return new Win32Window();
       // Win32Window erbt von GuiWindow
   }
}
</code></pre>
<p>Im Programm existiert dann jeweils eine globale Instanz der GuiFactory und die Instanzierung von neuen Fenstern schaut so aus:</p>
<pre><code class="language-cpp">#ifdef WIN32
        GuiFactory* GUI_FACTORY = new Win32Factory();
    #endif
    //...

    GuiWindow *myWindow = GUI_FACTORY-&gt;CreateWindow();
</code></pre>
<p>Allerdings finde ich diesen Ansatz eher &quot;hässlich&quot; und schwer zu warten, weil ich überall im System mit Zeigern rumhantieren muss.<br />
Gibt es hier einen alternativen Ansatz, der vielleicht auf eine Lösung per Templates hinausläuft? Oder eine Möglichkeit, mit der ich diese Objekthierachie kapseln kann?</p>
<p>Mein zweites Problem betrifft die Umsetzung des betriebssystemspezifischen &quot;Event-Listeners&quot;. In der Windowsimplementierung fängt eine Klasse Nachrichten mithilfe einer statischen WindowProc-Funktion und leitet sie an eine Instanz meines Event-Listeners. Dabei werden automatisch die betriebssystemsspezifischen Nachrichten in meine Lib-spezifischen Nachrichten mittels einer Abbildung(in dem Falle eine große std::map) umgesetzt.<br />
Wie lösen die anderen Gui-Libs diese Vorhaben? Gibts es alternative Möglichkeiten, die mich weniger Abhängig von den betriebssystemspezifischen Methoden der Nachrichtenbehandlung machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/243870/polymorphe-objekthierachie-kapseln</link><generator>RSS for Node</generator><lastBuildDate>Fri, 03 Apr 2026 20:01:23 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/243870.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 22 Jun 2009 12:35:20 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Mon, 22 Jun 2009 12:35:20 GMT]]></title><description><![CDATA[<p>Hallo,<br />
ich versuche mich gerade an einer kleinen GUI-Lib, die (zumindest) auf Linux und Windows das native Zeichnen von Festern u.ä. ermöglichen soll. Ich bediene mich dabei dem &quot;Abstract Factory Pattern&quot;, indem ich für die verschiedene Betriebssysteme jeweils verschiedene &quot;GUI-Factories&quot; implementiere, was dann ungefähr so aussieht:</p>
<pre><code class="language-cpp">// GuiFactory.h
class GuiFactory{
public:
   virtual GuiWindow* CreateWindow() =0;
}

// Win32Factory.h
#include &quot;GuiFactory.h&quot;
#include &quot;Win32Window.h&quot;    
class Win32Factory : public GuiFactory{
public:
   GuiWindow* CreateWindow(){
       return new Win32Window();
       // Win32Window erbt von GuiWindow
   }
}
</code></pre>
<p>Im Programm existiert dann jeweils eine globale Instanz der GuiFactory und die Instanzierung von neuen Fenstern schaut so aus:</p>
<pre><code class="language-cpp">#ifdef WIN32
        GuiFactory* GUI_FACTORY = new Win32Factory();
    #endif
    //...

    GuiWindow *myWindow = GUI_FACTORY-&gt;CreateWindow();
</code></pre>
<p>Allerdings finde ich diesen Ansatz eher &quot;hässlich&quot; und schwer zu warten, weil ich überall im System mit Zeigern rumhantieren muss.<br />
Gibt es hier einen alternativen Ansatz, der vielleicht auf eine Lösung per Templates hinausläuft? Oder eine Möglichkeit, mit der ich diese Objekthierachie kapseln kann?</p>
<p>Mein zweites Problem betrifft die Umsetzung des betriebssystemspezifischen &quot;Event-Listeners&quot;. In der Windowsimplementierung fängt eine Klasse Nachrichten mithilfe einer statischen WindowProc-Funktion und leitet sie an eine Instanz meines Event-Listeners. Dabei werden automatisch die betriebssystemsspezifischen Nachrichten in meine Lib-spezifischen Nachrichten mittels einer Abbildung(in dem Falle eine große std::map) umgesetzt.<br />
Wie lösen die anderen Gui-Libs diese Vorhaben? Gibts es alternative Möglichkeiten, die mich weniger Abhängig von den betriebssystemspezifischen Methoden der Nachrichtenbehandlung machen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1730970</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1730970</guid><dc:creator><![CDATA[Matzer]]></dc:creator><pubDate>Mon, 22 Jun 2009 12:35:20 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Mon, 22 Jun 2009 13:33:52 GMT]]></title><description><![CDATA[<p>Hallo Matzer,</p>
<p>zumal du nie zwei verschiedene Versionen einer dieser Window-Klassen (gleichzeitig) kompilieren wirst,<br />
ist Polymorpie sicherlich der falsche Weg.</p>
<p>Ich würde sowas etwa so machen:</p>
<pre><code class="language-cpp">// plattformunabhängig includes

#include &lt;string&gt;

// plattformabhängige includes

#ifdef WIN32
#include &lt;windows.h&gt;
#endif

class Window{

// Bereich für Funktionen, Konstruktoren und Member-Variablen, die in deiner Lib plattform-unabhängig implementiert sind

public:
	Window(const std::string&amp; title);
	~Window();
	void show();
	void setTitle(const std::string&amp; title); // setzen der Variablen und setTitleInternal aufruf

private:
	std::string title;

// Bereich für Funktionen, Konstruktoren und Member-Variablen, die in deiner Lib plattform-abhängig sind, aber auf jeder Plattform vorhanden

	void setTitleInternal(const std::string&amp; title); // Zugriff über das Handle um Fenster umzubennenen

// Bereich für Funktionen, Konstruktoren und Member-Variablen, die plattformabhängige Daten enthalten

#ifdef WIN32
private:
	HWND hwnd;
#endif

};
</code></pre>
<p>In den .cpp-Dateien kannst du dann die unteren beiden Bereiche sauber in _win.cpp und _linux.cpp untergliedern.</p>
<p>Erste Möglichkeit:<br />
window.cpp:</p>
<pre><code class="language-cpp">// plattformunabhängige Konstruktoren und Funktionen
// ...

// include der separaten Datein
#ifdef WIN32
#include &quot;window_win.cpp&quot;
#endif
</code></pre>
<p>Zweite Möglichkeit:<br />
Je nach betriebssystem unterschiedliche make-files, die dir dann sowohl<br />
window.cpp als auch z.B. window_win.cpp separat kompilieren.</p>
<p>Gruß,<br />
CSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1731002</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1731002</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Mon, 22 Jun 2009 13:33:52 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Tue, 23 Jun 2009 11:14:34 GMT]]></title><description><![CDATA[<p>Ok, vielen Dank erstmal für den Hinweis. Ich habe nur leider unterschlagen, dass die Klasse GuiWindow wieder von einer weiteren Klasse &quot;GuiBase&quot; erbt. D.h. von dieser einen Basisklasse erben zunächst einmal alle abstrakten Klassen:</p>
<pre><code class="language-cpp">class GuiBase{
   public:
   virtual void Show()=0;
   // alle Methoden, die von allen Gui-Objekten unterstützt werden sollen
};

class GuiWindow : public GuiBase{
   public:
   virtual void Show()=0;
};

class Win32Window : public GuiWindow{
   public:
   void Show(){
       //Implementierung
   }
};
</code></pre>
<p>Kann ich in diesem Fall überhaupt auf Polymorphie verzichten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1731531</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1731531</guid><dc:creator><![CDATA[Matzer]]></dc:creator><pubDate>Tue, 23 Jun 2009 11:14:34 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Tue, 23 Jun 2009 15:53:04 GMT]]></title><description><![CDATA[<p>Hi Matzer,</p>
<p>du brauchst nicht krampfhaft versuchen auf Polymorphie zu verzichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Ich wollte nur sagen, dass es keinen Sinn macht eine (vituelle) Basisklasse zu erstellen,<br />
die nur von einer Klasse (pro Betriebssystem) erbt.</p>
<p>Die Win32Window-Klasse würde ich mir sparen und in der GuiWindow-Klasse das<br />
machen, was ich vorher beschrieben habe.</p>
<p>Gruß,<br />
CSpille</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1731684</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1731684</guid><dc:creator><![CDATA[[[global:guest]]]]></dc:creator><pubDate>Tue, 23 Jun 2009 15:53:04 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Tue, 23 Jun 2009 19:33:29 GMT]]></title><description><![CDATA[<blockquote>
<p>du brauchst nicht krampfhaft versuchen auf Polymorphie zu verzichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Ich versuche nur auf möglichst viel Zeiger-&quot;Gefrickel&quot; zu verzichten <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /> Und meistens finde ich Template-Ansätze meist deutlich schöner, weswegen ich nach einem alternativen Weg der Implementierung gefragt hatte.<br />
Wobei man an dieser Stelle natürlich sagen muss, dass eine GUI-Library für Polymorphie praktisch prädestiniert ist.<br />
Letztlich hat man aber überall im Code mit Zeigern zu hantieren, wobei sich spätestens bei der Freigabe des Speichers die Frage stellt, welche Klasse diese Aufgabe nun übernehmen soll. Vielleicht sollte ich es mal erstnhaft in Betracht ziehen, shared_ptr zu verwenden <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /></p>
<p>Bezüglich meines Problems mit der Nachrichtenbehandlung bin ich nun auf boost::asio gestoßen. Ich war bisher felsenfest davon überzeugt, dass die Lib nur für die &quot;Netzwerkprogrammierung&quot; interessant zu seien scheint, aber tatsächlich lässt sich damit ziemlich elegant ein Event-Listener implementieren. Mal gucken was ich draus machen kann ^^.</p>
<p>Und nochmals danke für den Hinweis!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1731789</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1731789</guid><dc:creator><![CDATA[Matzer]]></dc:creator><pubDate>Tue, 23 Jun 2009 19:33:29 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Wed, 24 Jun 2009 22:28:31 GMT]]></title><description><![CDATA[<p>Ich glaube, ich würde für die <strong>betriebssystemspezifischen</strong> Klassen tatsächlich auf Polymorphie verzichten. Vielmehr würde ich mehrere parallele Hierarchien implementieren, für jedes OS eine. Die Klassen dort müssten natürlich identische (public) Schnittstellen haben. Für den User des Frameworks (und für nicht spezifische Klassen des Frameworks) würde ich lediglich typedefs definieren, die eine spezifische Klasse auf einen allgemeinen Namen abbilden.</p>
<pre><code class="language-cpp">--- Datei Win32EditField.hpp ---
class Win32EditField: public GuiBase {

   // ...

};

--- Datei LinuxEditField.hpp ---
class LinuxEditField: public GuiBase {

   // ...

};

--- Datei EditField.hpp ---
#ifdef COMPILE_WINDOWS
   #include &quot;Win32EditField.hpp&quot;
   #define EditField Win32EditField
#else
   #include &quot;LinuxEditField.hpp&quot;
   #define EditField LinuxEditField
#endif
</code></pre>
<p>Natürlich müsste man dann in den Makefiles dafür sorgen, dass nur die passenden Dateien gebaut werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1732448</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1732448</guid><dc:creator><![CDATA[Grautvornix]]></dc:creator><pubDate>Wed, 24 Jun 2009 22:28:31 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Thu, 25 Jun 2009 01:58:44 GMT]]></title><description><![CDATA[<p>CSpille</p>
<blockquote>
<p>zumal du nie zwei verschiedene Versionen einer dieser Window-Klassen (gleichzeitig) kompilieren wirst,</p>
</blockquote>
<p>Ach?</p>
<blockquote>
<p>ist Polymorpie sicherlich der falsche Weg.</p>
</blockquote>
<p>Mal die fragwürdigkeit der ersten Aussage ausser Acht gelassen...:<br />
Wieso?</p>
<blockquote>
<p>Ich versuche nur auf möglichst viel Zeiger-&quot;Gefrickel&quot; zu verzichten</p>
</blockquote>
<p>Dann frickel halt nicht. Nimm halt Smart Pointer.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1732464</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1732464</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 25 Jun 2009 01:58:44 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Thu, 25 Jun 2009 09:56:01 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>CSpille</p>
<blockquote>
<p>zumal du nie zwei verschiedene Versionen einer dieser Window-Klassen (gleichzeitig) kompilieren wirst,</p>
</blockquote>
<p>Ach?</p>
<blockquote>
<p>ist Polymorpie sicherlich der falsche Weg.</p>
</blockquote>
<p>Mal die fragwürdigkeit der ersten Aussage ausser Acht gelassen...:<br />
Wieso?</p>
<blockquote>
<p>Ich versuche nur auf möglichst viel Zeiger-&quot;Gefrickel&quot; zu verzichten</p>
</blockquote>
<p>Dann frickel halt nicht. Nimm halt Smart Pointer.</p>
</blockquote>
<p>1. Er wird niemals zwei verschiedene Versionen der Window-Klassen kompilieren, weil Win32Window wohl kaum unter Linux und LinuxWindow wohl kaum unter Windows compiliert. Wieso also &quot;Ach?&quot;?</p>
<p>2. In sofern ist Polymorphie definitiv der falsche Weg.</p>
<p>3. Unter &quot;Zeiger-Gefrickel&quot; verstand ich, dass wirklich ausschließlich Zeiger verwendet werden können (ob smart oder nicht), wenn man so vorgeht. Das ist Gefrickel und vollkommen unangemessen. Ich würde mich mit einer solchen Libaray nicht wohlfühlen.</p>
<p>Man sehe sich Qt an. Da können Controls wie ganz normale Objekte beispielsweise auch als Instanzvariablen angelegt werden. Keine AbstractFactorys.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1732582</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1732582</guid><dc:creator><![CDATA[Grautvornix]]></dc:creator><pubDate>Thu, 25 Jun 2009 09:56:01 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Thu, 25 Jun 2009 12:20:56 GMT]]></title><description><![CDATA[<p>Matzer schrieb:</p>
<blockquote>
<p>Ich versuche nur auf möglichst viel Zeiger-&quot;Gefrickel&quot; zu verzichten</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Dann frickel halt nicht. Nimm halt Smart Pointer.</p>
</blockquote>
</blockquote>
<p>Grautvornix schrieb:</p>
<blockquote>
<p>3. Unter &quot;Zeiger-Gefrickel&quot; verstand ich, dass wirklich ausschließlich Zeiger verwendet werden können (ob smart oder nicht), wenn man so vorgeht. Das ist Gefrickel und vollkommen unangemessen. Ich würde mich mit einer solchen Libaray nicht wohlfühlen.</p>
<p>Man sehe sich Qt an. Da können Controls wie ganz normale Objekte beispielsweise auch als Instanzvariablen angelegt werden. Keine AbstractFactorys.</p>
</blockquote>
<p>Genau das meinte ich. Nach außen hin, d.h. für den Benutzer der Lib (in dem Fall wohl nur ich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> ) sollten so wenig Zeiger wie möglich verwendet werden. Dies ist aber durch das Design der Abstract Factory praktisch unmöglich. Und das macht die Lib unangenehm zu benutzen. Insbesondere solche Konstrukte:</p>
<pre><code class="language-cpp">GuiFactory-&gt;CreateWindow();
</code></pre>
<p>finde ich persönlich ziemlich hässlich.<br />
In diesem Fall sollte ich die Version von Grautvornix vorziehen und die betriebssystemspezifischen Sachen jeweils in separate Hierachien einteilen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1732674</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1732674</guid><dc:creator><![CDATA[Matzer]]></dc:creator><pubDate>Thu, 25 Jun 2009 12:20:56 GMT</pubDate></item><item><title><![CDATA[Reply to polymorphe Objekthierachie kapseln on Thu, 25 Jun 2009 17:59:08 GMT]]></title><description><![CDATA[<p>Matzer schrieb:</p>
<blockquote>
<p>Genau das meinte ich. Nach außen hin, d.h. für den Benutzer der Lib (in dem Fall wohl nur ich <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f642.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--slightly_smiling_face"
      title=":)"
      alt="🙂"
    /> ) sollten so wenig Zeiger wie möglich verwendet werden. Dies ist aber durch das Design der Abstract Factory praktisch unmöglich. Und das macht die Lib unangenehm zu benutzen. Insbesondere solche Konstrukte:</p>
<pre><code class="language-cpp">GuiFactory-&gt;CreateWindow();
</code></pre>
<p>finde ich persönlich ziemlich hässlich.<br />
In diesem Fall sollte ich die Version von Grautvornix vorziehen und die betriebssystemspezifischen Sachen jeweils in separate Hierachien einteilen.</p>
</blockquote>
<p>Der User (in diesem Fall wohl nur du <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /> ) wird's dir danken!</p>
<p>Ist dir übrigens klar, was du dir mit einer solchen Library antust?! Ich habe dasselbe auch schonmal gemacht, und zwar nur für Windows, also nicht einmal portabel. Das hat sich gelohnt, war aber ne Wahnsinnsarbeit. Damit habe ich mir dann meinen Nick redlich verdient <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Stefan aka Grautvornix.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1732840</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1732840</guid><dc:creator><![CDATA[Grautvornix]]></dc:creator><pubDate>Thu, 25 Jun 2009 17:59:08 GMT</pubDate></item></channel></rss>