<?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[class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie?]]></title><description><![CDATA[<p>Also... voraus schonmal entschuldigung das es sich hierbei um Crossposting handelt, da ich auch schon in <a href="http://www.spieleprogrammierer.de/phpBB2/" rel="nofollow">www.spieleprogrammierer.de/phpBB2/</a> die Frage gestellt habe, allerdings brauch ich es dringend und das dauert dort zu lange.</p>
<pre><code class="language-cpp">#if !defined (RC_SINGLETON_H__INCLUDED)
#define RC_SINGLETON_H__INCLUDED

#if (_MSC_VER &gt; 1000)
#pragma once
#endif

namespace realcay
{
    template &lt;class T&gt;
    class RCWINDOW_API Singleton
    {
    public:
        inline static T&amp; instance() { static T inst; return inst; }

    protected:
        Singleton();

        public:
        Singleton(const Singleton&amp;);
        Singleton&amp; operator=(const Singleton&amp;);
    };
};
#endif // RC_SINGLETON_H__INCLUDED
</code></pre>
<p>ist mein Singleton. Dieser liegt in einer DLL ...</p>
<p>Jetzt habe ich eine Klasse ... nennen wir sie &quot;base&quot;, die unter anderem folgende Funktionen (oder so ähnlich ;)) drin hat:</p>
<pre><code class="language-cpp">#include &lt;map&gt;
#define AE_RENDER 1
#define AE_USER 11

class base : public realcay::Singleton&lt;base&gt;
{
    typedef void (base::*EventHandler)(const void*);

private:
    std::map&lt;std::size_t, EventHandler&gt; m_Hndls;

public:
    void send_message(std::size_t id, const void* data)
    {
        std::map&lt;std::size_t, EventHandler&gt;::iterator it = m_Hndls.find(id);
        if (it != m_Hndls.end()) (*this.*it-&gt;second)(data);
    }
    void register_message(std::size_t id, EventHandler hdnl)
    { m_Hndls[id] = hdnl; }
};
</code></pre>
<p>Soweit ist ja alles selbsterklärend ... oder? Man kann halt ein Event registrieren (register_message), AE_RENDER usw., und wenn man dann base::instance().send_message aufruft, wird gegebenen Falls die Funktion die registriert wurde, aufgerufen.</p>
<p>Nun sieht man ja an der definition von EventHandler, dass es eine von base abgeleitete Klasse sein muss, um eine Memberfunktion derer problemlos in<br />
einen EventHandler casten zu können. Also kommt eine Klasse derived ins Spiel:</p>
<pre><code class="language-cpp">class derived : public base
{
public:
     derived() : m_int(0) { register_message(AE_RENDER, &amp;derived::on_render); }

private:
     void on_render(const void* data) { std::cout &lt;&lt; m_int &lt;&lt; std::endl; }

private:
    int m_int;
};
</code></pre>
<p>Jetzt hab ich aber ein Problem mit instance(), da diese Funktion ja ein Objekt von base erstellt, ein derived-Objekt wird aber nie erstellt! Gerade das ist aber von nöten.</p>
<p>Nun könnte ich ja bsw. hingehen und aus base ebenfalls eine template-Klasse machen ... geht aber nicht, da ich in der DLL die Klasse base schon nutze und da ist mir der Name von der abgeleiteten Klasse noch nicht bekannt!<br />
Wie könnte man das Problem umgehen? Hat jemand eine Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/189372/class-base-public-singleton-lt-base-gt-class-derived-public-base-wie</link><generator>RSS for Node</generator><lastBuildDate>Fri, 25 Sep 2026 08:59:30 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/189372.rss" rel="self" type="application/rss+xml"/><pubDate>Sun, 12 Aug 2007 08:58:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Sun, 12 Aug 2007 08:58:05 GMT]]></title><description><![CDATA[<p>Also... voraus schonmal entschuldigung das es sich hierbei um Crossposting handelt, da ich auch schon in <a href="http://www.spieleprogrammierer.de/phpBB2/" rel="nofollow">www.spieleprogrammierer.de/phpBB2/</a> die Frage gestellt habe, allerdings brauch ich es dringend und das dauert dort zu lange.</p>
<pre><code class="language-cpp">#if !defined (RC_SINGLETON_H__INCLUDED)
#define RC_SINGLETON_H__INCLUDED

#if (_MSC_VER &gt; 1000)
#pragma once
#endif

namespace realcay
{
    template &lt;class T&gt;
    class RCWINDOW_API Singleton
    {
    public:
        inline static T&amp; instance() { static T inst; return inst; }

    protected:
        Singleton();

        public:
        Singleton(const Singleton&amp;);
        Singleton&amp; operator=(const Singleton&amp;);
    };
};
#endif // RC_SINGLETON_H__INCLUDED
</code></pre>
<p>ist mein Singleton. Dieser liegt in einer DLL ...</p>
<p>Jetzt habe ich eine Klasse ... nennen wir sie &quot;base&quot;, die unter anderem folgende Funktionen (oder so ähnlich ;)) drin hat:</p>
<pre><code class="language-cpp">#include &lt;map&gt;
#define AE_RENDER 1
#define AE_USER 11

class base : public realcay::Singleton&lt;base&gt;
{
    typedef void (base::*EventHandler)(const void*);

private:
    std::map&lt;std::size_t, EventHandler&gt; m_Hndls;

public:
    void send_message(std::size_t id, const void* data)
    {
        std::map&lt;std::size_t, EventHandler&gt;::iterator it = m_Hndls.find(id);
        if (it != m_Hndls.end()) (*this.*it-&gt;second)(data);
    }
    void register_message(std::size_t id, EventHandler hdnl)
    { m_Hndls[id] = hdnl; }
};
</code></pre>
<p>Soweit ist ja alles selbsterklärend ... oder? Man kann halt ein Event registrieren (register_message), AE_RENDER usw., und wenn man dann base::instance().send_message aufruft, wird gegebenen Falls die Funktion die registriert wurde, aufgerufen.</p>
<p>Nun sieht man ja an der definition von EventHandler, dass es eine von base abgeleitete Klasse sein muss, um eine Memberfunktion derer problemlos in<br />
einen EventHandler casten zu können. Also kommt eine Klasse derived ins Spiel:</p>
<pre><code class="language-cpp">class derived : public base
{
public:
     derived() : m_int(0) { register_message(AE_RENDER, &amp;derived::on_render); }

private:
     void on_render(const void* data) { std::cout &lt;&lt; m_int &lt;&lt; std::endl; }

private:
    int m_int;
};
</code></pre>
<p>Jetzt hab ich aber ein Problem mit instance(), da diese Funktion ja ein Objekt von base erstellt, ein derived-Objekt wird aber nie erstellt! Gerade das ist aber von nöten.</p>
<p>Nun könnte ich ja bsw. hingehen und aus base ebenfalls eine template-Klasse machen ... geht aber nicht, da ich in der DLL die Klasse base schon nutze und da ist mir der Name von der abgeleiteten Klasse noch nicht bekannt!<br />
Wie könnte man das Problem umgehen? Hat jemand eine Idee?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343053</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343053</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Sun, 12 Aug 2007 08:58:05 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Sun, 12 Aug 2007 09:29:09 GMT]]></title><description><![CDATA[<p>Das geht so wie du es vorhast garnicht. Ist aber auch nicht besonders sinnvoll, denn da du aus base ein singleton gemacht hast, kann es nur ein einziges base-objekt geben, inclusive aller abgeleiteten Klassen. Sprich, du könntest zwar noch eine klasse derived2 von base ableiten, müsstest dann aber überlegen ob du nur ein Objekt von derived oder eins von derived2 haben willst. Was widerum die Klassenhierarchie an sich fragwürdig macht.<br />
Mögliche Lösungen sind:</p>
<p>a) du packst alles was du in derived hast gleich in base rein, wenn du eh keine weitere Klasse von base ableien willst.</p>
<p>b) du machst derived zum Singleton an Stelle von base. Stichwort mehrfache Vererbung. Dann kannst du mehrere abgeleitete Singletons und nicht-singletons haben, die das Verhalten von base erben</p>
<p>c) wenn du tatsächlich ein globales Singleton Objekt benötigst, das aber je nach Umgebungsbedingungen verschiedene Ausprägungen haben soll, dann werden diese verschiedenen Ausprägungen ja alle das selbe Interface haben. dann sollte dein Singleton nur das Interface zur Verfügung stellen und alles andere einem Implementierungs-Objekt überlassen, das du ihm zur Laufzeit gibst.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343066</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343066</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Sun, 12 Aug 2007 09:29:09 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Sun, 12 Aug 2007 09:39:03 GMT]]></title><description><![CDATA[<p>Nunja das Problem ist halt, das ich base als Singleton schon innerhalb der DLL benötige, d.h. kann ich es nicht nur als &quot;normale&quot; Klasse anlegen und zum anderen will ich nicht, das man von base ableiten <strong>muss</strong> aber kann... also das man, wenn man keine extra Funktionen hat, einfach base nutzen kann(man muss ja nicht unbedingt eine message registriert haben!) und wenn doch, das man dann eine abgeleitete Klasse anlegen muss ...</p>
<p>a) Fällt raus, da es unterschiedliche Teilprogramme sind. Die DLL ist nur das Interface ...<br />
b) Fällt raus ... s.o.<br />
c) wie du meine?</p>
<p>Nja werd sonnst in dem Singleton einfach nur einen Pointer speichern, den man dann am Anfang initialisieren muss ... d.h.</p>
<pre><code class="language-cpp">class base
{
    typedef void (base::*EventHandler)(const void*);

private:
    std::map&lt;std::size_t, EventHandler&gt; m_Hndls;

public:
    void send_message(std::size_t id, const void* data)
    {
        std::map&lt;std::size_t, EventHandler&gt;::iterator it = m_Hndls.find(id);
        if (it != m_Hndls.end()) (*this.*it-&gt;second)(data);
    }
    void register_message(std::size_t id, EventHandler hdnl)
    { m_Hndls[id] = hdnl; }

public:
    inline static base* instance(base* ptr = NULL) { static base* inst = ptr; return inst; }
};
</code></pre>
<p>...</p>
<pre><code class="language-cpp">int main()
{
    derived inst;
    derived::instance(&amp;inst);
}
</code></pre>
<p>oder so ähnlich ...<br />
nen besserne Vorschlag? <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="😃"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343071</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343071</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Sun, 12 Aug 2007 09:39:03 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Sun, 12 Aug 2007 09:47:50 GMT]]></title><description><![CDATA[<p>Von einer Singleton-Klasse abzuleiten, fuert den Singleton ad absurdum. Steht doch in jedem Buch...</p>
<p>Ausserdem, wozu du dir die Muehe machst einen operator= zu schreiben fuer einen Singleton, entzieht sich auch meinem Verstaendnis (gilt auch fuer den Copy-Constr.).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343074</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343074</guid><dc:creator><![CDATA[DEvent]]></dc:creator><pubDate>Sun, 12 Aug 2007 09:47:50 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Sun, 12 Aug 2007 09:48:48 GMT]]></title><description><![CDATA[<p>der sollte eigentlich auch rpivate sein ... hab hier nen tippfehler drin.</p>
<blockquote>
<p>Ausserdem, wozu du dir die Muehe machst einen operator= zu schreiben fuer einen Singleton, entzieht sich auch meinem Verstaendnis (gilt auch fuer den Copy-Constr.).</p>
</blockquote>
<p>damit man se nciht nutzen kann setz ich se privat ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343077</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343077</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Sun, 12 Aug 2007 09:48:48 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Sun, 12 Aug 2007 16:45:36 GMT]]></title><description><![CDATA[<p>Ich würd sagen da haberts grundlegend am Design. Oo</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343238</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343238</guid><dc:creator><![CDATA[David_pb]]></dc:creator><pubDate>Sun, 12 Aug 2007 16:45:36 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Mon, 13 Aug 2007 08:49:35 GMT]]></title><description><![CDATA[<p>Wie bereits gesagt, es ist relativ sinnfrei, von einem Singleton ableiten zu wollen. Denn jedes Objekt der abgeleiteten Klassen beinhaltet ja ein Objekt der Basisklasse. Von daher kannst du nur EIN objekt von GENAU EINER der abgeleiteten Klassen erstellen. Wenn du allerdings, wie du im ersten post sschon schreibst, in der DLL schon die Klasse base benutzt, kannst du davon garnicht mehr ableiten, weil jede Instanz einer abgeleiteten Klasse eine Instanz von base enthaelt - was wegen der Singleton-Eigenschaft von base aber nicht geht. Insofern hat david_pb schon recht dass es da irgendwo am deigns hapert.</p>
<p>Was ich mit c) ausdruecken wollte: Wenn du dem Klienten die Moeglichkeit geben willst, gewisse Features zu Base hinzuzufuegen, kannst du in base dafuer eine Schnittstelle anbieten, allerdings ist der KLient dann daruf beschraenkt. Bsp:</p>
<pre><code class="language-cpp">class base : public singleton&lt;base&gt;
{
public:
  void changeimpl(baseImpl* newimpl) {delete impl; impl = newimpl;}

  void ichweisswas1() {cout &lt;&lt; &quot;ich weiss was 1&quot; &lt;&lt; endl;}

  //schnittstelle fuer klient:
  void weissnich1() {imol-&gt;weissnich1();} 
  void weissnich2() {impl-&gt;weissnich2();}
private:
  baseImpl* impl;
  base() : impl(0) {};
  ~base() {delete impl;}
};

class baseImpl 
{
  virtual void weissnich1() = 0;
  virtual void weissnich2() = 0;
}
</code></pre>
<p>So kann der Klient mit changeimpl seine eigene Version der Schnittstelle &quot;weissnich&quot; in die base klasse &quot;injizieren&quot;, ohne deren Singleton Eigenschaft aufzubrechen</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343545</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343545</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Mon, 13 Aug 2007 08:49:35 GMT</pubDate></item><item><title><![CDATA[Reply to class base : public Singleton&amp;lt;base&amp;gt;; class derived : public base ... wie? on Mon, 13 Aug 2007 12:27:57 GMT]]></title><description><![CDATA[<p>Nja wäre so natürlich auch möglich ... hatte an sowas ähnliches auch schon gedacht gehabt ... für den Zweck reicht aber vollkommen die Funktion die ich oben habe ... auch wenn es sich nicht mehr um einen richtigen Singleton handelt ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1343676</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1343676</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Mon, 13 Aug 2007 12:27:57 GMT</pubDate></item></channel></rss>