<?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[Generisches Observer-Pattern mit void-Zeiger?!]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich möchte das Observerpattern einsetzen, allerdings reicht es mir nicht aus, &quot;genotified&quot; zu werden. Ich brauche den Zeiger auf das Objekt, damit ich entsprechend reagieren kann. Trotzdem soll mein Observer-Pattern generisch sein, damit ich nicht jedes Mal Code erzeugen muss, nur weil der Observer jetzt anders ist.</p>
<p>Meine Idee war jetzt folgende:</p>
<pre><code class="language-cpp">class IObservable {
   public:
      virtual ~IObservable() {}

      void attach (Observer* pObserver) {
         observers.push_back(pObserver);
		}

      void notify() {   
			 for (size_t i=0; i&lt;observers.size(); ++i) {
				observers[i]-&gt;update(this);
			 }
         }
   private:
      std::vector&lt;Observer*&gt; observers;
};
</code></pre>
<p>Dazu der Observer:</p>
<pre><code class="language-cpp">class Observer {
	public:
	    virtual ~Observer() {}
	    virtual void update(void* pSubject) = 0;
};
</code></pre>
<p>Ich habe mich dabei versucht, an Java zu orientieren. Dort wird der Updatemethode zum einen das Observable-Objekt übergeben und zum anderen ein &quot;Object&quot; als Argument. Das versuche ich mit dem void-Zeiger nachzubilden, da es in C++ ja keine &quot;OberBasisklasse&quot; gibt.</p>
<p>Frage Nr. 1) Hat wer andere Ideen, die besser sind als meine?</p>
<p>Frage Nr. 2) Ist meine Idee überhaupt realisierbar? Mein Programm läuft genau solange gut, wie ich nicht versuche, einen Downcast durchzuführen:</p>
<p>Geht:</p>
<pre><code class="language-cpp">cout&lt;&lt;&quot;Observer::Update aufgerufen&quot;&lt;&lt;pSubject&lt;&lt;endl;
</code></pre>
<p>Geht nicht (stürzt dann an einer ganz anderen Stelle im Objekt ab)</p>
<pre><code class="language-cpp">cout&lt;&lt;&quot;Observer::Update aufgerufen &quot;&lt;&lt;static_cast&lt;I2DGeometry*&gt;(pSubject)-&gt;getPosition().x&lt;&lt;endl;
</code></pre>
<p>Danke für's Zuhören</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/290211/generisches-observer-pattern-mit-void-zeiger</link><generator>RSS for Node</generator><lastBuildDate>Tue, 18 Aug 2026 16:48:55 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/290211.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 21 Jul 2011 13:27:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 13:27:28 GMT]]></title><description><![CDATA[<p>Hallo!</p>
<p>Ich möchte das Observerpattern einsetzen, allerdings reicht es mir nicht aus, &quot;genotified&quot; zu werden. Ich brauche den Zeiger auf das Objekt, damit ich entsprechend reagieren kann. Trotzdem soll mein Observer-Pattern generisch sein, damit ich nicht jedes Mal Code erzeugen muss, nur weil der Observer jetzt anders ist.</p>
<p>Meine Idee war jetzt folgende:</p>
<pre><code class="language-cpp">class IObservable {
   public:
      virtual ~IObservable() {}

      void attach (Observer* pObserver) {
         observers.push_back(pObserver);
		}

      void notify() {   
			 for (size_t i=0; i&lt;observers.size(); ++i) {
				observers[i]-&gt;update(this);
			 }
         }
   private:
      std::vector&lt;Observer*&gt; observers;
};
</code></pre>
<p>Dazu der Observer:</p>
<pre><code class="language-cpp">class Observer {
	public:
	    virtual ~Observer() {}
	    virtual void update(void* pSubject) = 0;
};
</code></pre>
<p>Ich habe mich dabei versucht, an Java zu orientieren. Dort wird der Updatemethode zum einen das Observable-Objekt übergeben und zum anderen ein &quot;Object&quot; als Argument. Das versuche ich mit dem void-Zeiger nachzubilden, da es in C++ ja keine &quot;OberBasisklasse&quot; gibt.</p>
<p>Frage Nr. 1) Hat wer andere Ideen, die besser sind als meine?</p>
<p>Frage Nr. 2) Ist meine Idee überhaupt realisierbar? Mein Programm läuft genau solange gut, wie ich nicht versuche, einen Downcast durchzuführen:</p>
<p>Geht:</p>
<pre><code class="language-cpp">cout&lt;&lt;&quot;Observer::Update aufgerufen&quot;&lt;&lt;pSubject&lt;&lt;endl;
</code></pre>
<p>Geht nicht (stürzt dann an einer ganz anderen Stelle im Objekt ab)</p>
<pre><code class="language-cpp">cout&lt;&lt;&quot;Observer::Update aufgerufen &quot;&lt;&lt;static_cast&lt;I2DGeometry*&gt;(pSubject)-&gt;getPosition().x&lt;&lt;endl;
</code></pre>
<p>Danke für's Zuhören</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2096092</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096092</guid><dc:creator><![CDATA[Observer5000]]></dc:creator><pubDate>Thu, 21 Jul 2011 13:27:28 GMT</pubDate></item><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 13:45:01 GMT]]></title><description><![CDATA[<p>Mach den Observer zu einem Template. <code>void*</code> ist selten eine Lösung. Und Java würde ich mir bei solchen Dingen nicht als Vorbild nehmen, weil solche Dinge dort oft anders gehandhabt werden.</p>
<p>Ansonsten könntest du dir vielleicht auch mal <a href="http://www.boost.org/doc/libs/1_47_0/doc/html/function.html" rel="nofollow">Boost.Function</a> anschauen. Gibts übrigens auch als <code>std::tr1::function</code> (TR1) und <code>std::function</code> (C++0x). Siehe auch <a href="http://www.c-plusplus.net/forum/289436" rel="nofollow">hier</a>...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2096096</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096096</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 21 Jul 2011 13:45:01 GMT</pubDate></item><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 14:36:31 GMT]]></title><description><![CDATA[<p>Warum übergibst du Update nicht ein Objekt vom Typ IObservable?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2096125</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096125</guid><dc:creator><![CDATA[IObservable]]></dc:creator><pubDate>Thu, 21 Jul 2011 14:36:31 GMT</pubDate></item><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 14:59:55 GMT]]></title><description><![CDATA[<p>Wenn überhaupt brauchst dafür einen reinterpret_cast.</p>
<p>Daraus ein template zu machen ist nur bedingt sinnvoll, außer man leitet von IObserver ab.</p>
<pre><code class="language-cpp">template &lt;class ObserverType&gt;
public TObserver : IObserver 
{
  TObserver(ObserverType* observerThis);
}

void YourManagerClass::RegisterObserver&lt;class ObserverType&gt;(ObserverType* observeThis)
{
  // std::vector&lt; IObserver* &gt; notifiers;
  notifiers.push_back(TObserver&lt;ObserverType&gt;(observerThis);
}

void YourManagerClass::notifiy();
{
 for_each(notifiers, note)
 {
   // Spätestens hier gibts einen cast
   note-&gt;YourBaseClassFunction(this);
 }
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2096137</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096137</guid><dc:creator><![CDATA[nurf]]></dc:creator><pubDate>Thu, 21 Jul 2011 14:59:55 GMT</pubDate></item><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 15:13:06 GMT]]></title><description><![CDATA[<p>nurf schrieb:</p>
<blockquote>
<p>Wenn überhaupt brauchst dafür einen reinterpret_cast.</p>
</blockquote>
<p>Ne, <code>void*</code> castet man mit <code>static_cast</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2096145</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096145</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 21 Jul 2011 15:13:06 GMT</pubDate></item><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 15:22:18 GMT]]></title><description><![CDATA[<p>Klingt mir ein wenig nach CRTP <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>
<pre><code class="language-cpp">template &lt;typename Observable&gt;
class IObservable
{
   public:
      virtual ~IObservable() {}

      void attach (Observer* pObserver) {
         observers.push_back(pObserver);
        }

      void notify() {   
             for (size_t i=0; i&lt;observers.size(); ++i) {
                observers[i]-&gt;update(static_cast&lt;Obserable&gt;(this));
             }
         }
   private:
      std::vector&lt;Observer*&gt; observers;
};

class DasDingDasObserviertWerdenSoll : public IObserable&lt;DasDingDasObserviertWerdenSoll&gt;
{
  //...
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2096150</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096150</guid><dc:creator><![CDATA[bmario]]></dc:creator><pubDate>Thu, 21 Jul 2011 15:22:18 GMT</pubDate></item><item><title><![CDATA[Reply to Generisches Observer-Pattern mit void-Zeiger?! on Thu, 21 Jul 2011 20:51:35 GMT]]></title><description><![CDATA[<p>Diese Templatelösung ist jetzt aber nicht viel besser, schließlich hat update jetzt wieder gezwungenermaßen einen Zeiger als Argument, den man evtl. nicht will.</p>
<p>In C++ gibt es mehr Möglichkeiten als in Java, weswegen ich einfach den signal/slot-Mechanismus anschauen würde. Dieser kann auf Methoden verweisen, nicht auf ganze Klassen. Das macht alles etwas dynamischer.</p>
<p>Eine Dynamik in dem Sinne, dass die Observable-Klasse allgemein bleiben soll, aber man trotzdem einen Zeiger übergibt, geht so nicht, da muss man eben eine Spezialisierung bauen.</p>
<pre><code class="language-cpp">#ifndef OBSERVABLE
#define OBSERVABLE

#include &lt;vector&gt;

// General Observable for different Observers and their needs 

template&lt;typename Observer&gt; 
class Observable 
{ 
private:
	typedef typename Observer ObserverType;

	typedef std::vector&lt;ObserverType*&gt; Observers; 
	typedef typename Observers::iterator ObserversIt;     
	Observers observers; 

protected: 
	Observers&amp; getObservers() {return observers;} 

public: 
	void AddObserver(ObserverType&amp; newObserver) {observers.push_back(&amp;newObserver);} 

	void notifyAll() 
	{ 
		for(ObserversIt it = observers.begin(); it != observers.end(); ++it) 
			notify(*it); // nebenbei noch Template Method Pattern angewendet; das hat aber nix mit C++ Templates zu tun
	} 

	virtual void notify(ObserverType*) = 0; 

	virtual ~Observable() {} 
}; 

#endif
</code></pre>
<pre><code class="language-cpp">#ifndef PUSHOBSERVER
#define PUSHOBSERVER

// PushObserver - a specific observer which gets notification of source 

class PushObservable; 

class PushObserver 
{ 
public:
	virtual void onNotification(PushObservable* source) = 0; 
};

#endif
</code></pre>
<pre><code class="language-cpp">#ifndef PUSHOBSERVABLE
#define PUSHOBSERVABLE

#include &quot;Observable.hpp&quot;
#include &quot;PushObserver.hpp&quot;

// PushObservable: A specific Observable which publishes the source 

class PushObservable : public Observable&lt;PushObserver&gt; 
{ 
public: 
	/*virtual*/ void notify(PushObserver* observer) 
	{ 
		observer-&gt;onNotification(this); 
	} 
};

#endif
</code></pre>
<p>Edit: So, ist jetzt auch kompilierbar.</p>
<p>Jetzt kann jeder Erbe vom Observable sich selbst aussuchen, was er dem jeweiligen Observer mitgibt. Aber ob das so wichtig ist... weiß ich nicht. Jedenfalls sind signal/slots deutlich kürzer und eleganter imo.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2096242</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2096242</guid><dc:creator><![CDATA[Eisflamme]]></dc:creator><pubDate>Thu, 21 Jul 2011 20:51:35 GMT</pubDate></item></channel></rss>