<?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 mit Vererbung und Templates]]></title><description><![CDATA[<p>Hallo alle miteinander,</p>
<p>ich möchte gern folgendes Programmieren, weiß aber nicht wie und ob es überhaupt möglich ist: Es geht um die Vererbung von Klassen. Sagen wir ich habe eine Basisklasse und möchte davon viele andere Klassen ableiten. In den abgeleiteten Klassen gibt es einen immer wechselnden Datentyp, der in diesen Klassen fest ist und für den es eine Menge Funktionen gibt. Nun weiß ich nicht ob es möglich ist in der Basisklasse einen Template Platzhalter anzugeben, der in den abgeleiteten Klassen instanziiert wird. Es soll ungefähr so aussehen:</p>
<pre><code class="language-cpp">class BASISKLASSE
{
    public:
        BASISKLASSE();
        virtual ~BASISKLASSE();

        template &lt;typename T&gt; virtual int setObject(T) = 0;
        template &lt;typename T&gt; virtual T getObject() = 0;
        template &lt;typename T&gt; virtual std::list&lt;T&gt; getQueryResult() = 0;

    private:
        template &lt;typename T&gt; T tObject;
}
</code></pre>
<pre><code class="language-cpp">struct MYOBJECT
{
    int i1;
    int i2;
}

class ABGEL_KLASSE : protected BASISKLASSE
{
    public:

        ABGEL_KLASSE();
        virtual ~ABGEL_KLASSE();

        virtual int setObject(&lt;MYOBJECT&gt;);
        virtual &lt;MYOBJECT&gt; getObject();
        virtual std::list&lt;MYOBJECT&gt; getQueryResult();

    private:
        &lt;MYOBJECT&gt; tObject;
}
</code></pre>
<p>Nach diesem Pseudocode wird es ja sicher nicht funktionieren, aber wie kann ich das realisieren?</p>
<p>Geht so etwas wie:</p>
<pre><code class="language-cpp">template &lt;typename T&gt; class BASISKLASSE
{
    public:
        BASISKLASSE();
        virtual ~BASISKLASSE();

        virtual int setObject(T) = 0;
        virtual T getObject() = 0;
        virtual std::list&lt;T&gt; getQueryResult() = 0;

    private:
        T tObject;
}
</code></pre>
<pre><code class="language-cpp">struct MYOBJECT
{
    int i1;
    int i2;
}

class ABGEL_KLASSE : protected BASISKLASSE&lt;MYOBJECT&gt;
{
    public:

        ABGEL_KLASSE();
        virtual ~ABGEL_KLASSE();

        virtual int setObject(T);
        virtual T getObject();
        virtual std::list&lt;T&gt; getQueryResult();

    private:
        T tObject;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/252453/klassendesign-mit-vererbung-und-templates</link><generator>RSS for Node</generator><lastBuildDate>Mon, 14 Sep 2026 05:43:54 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/252453.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 20 Oct 2009 07:43:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Klassendesign mit Vererbung und Templates on Tue, 20 Oct 2009 07:54:41 GMT]]></title><description><![CDATA[<p>Hallo alle miteinander,</p>
<p>ich möchte gern folgendes Programmieren, weiß aber nicht wie und ob es überhaupt möglich ist: Es geht um die Vererbung von Klassen. Sagen wir ich habe eine Basisklasse und möchte davon viele andere Klassen ableiten. In den abgeleiteten Klassen gibt es einen immer wechselnden Datentyp, der in diesen Klassen fest ist und für den es eine Menge Funktionen gibt. Nun weiß ich nicht ob es möglich ist in der Basisklasse einen Template Platzhalter anzugeben, der in den abgeleiteten Klassen instanziiert wird. Es soll ungefähr so aussehen:</p>
<pre><code class="language-cpp">class BASISKLASSE
{
    public:
        BASISKLASSE();
        virtual ~BASISKLASSE();

        template &lt;typename T&gt; virtual int setObject(T) = 0;
        template &lt;typename T&gt; virtual T getObject() = 0;
        template &lt;typename T&gt; virtual std::list&lt;T&gt; getQueryResult() = 0;

    private:
        template &lt;typename T&gt; T tObject;
}
</code></pre>
<pre><code class="language-cpp">struct MYOBJECT
{
    int i1;
    int i2;
}

class ABGEL_KLASSE : protected BASISKLASSE
{
    public:

        ABGEL_KLASSE();
        virtual ~ABGEL_KLASSE();

        virtual int setObject(&lt;MYOBJECT&gt;);
        virtual &lt;MYOBJECT&gt; getObject();
        virtual std::list&lt;MYOBJECT&gt; getQueryResult();

    private:
        &lt;MYOBJECT&gt; tObject;
}
</code></pre>
<p>Nach diesem Pseudocode wird es ja sicher nicht funktionieren, aber wie kann ich das realisieren?</p>
<p>Geht so etwas wie:</p>
<pre><code class="language-cpp">template &lt;typename T&gt; class BASISKLASSE
{
    public:
        BASISKLASSE();
        virtual ~BASISKLASSE();

        virtual int setObject(T) = 0;
        virtual T getObject() = 0;
        virtual std::list&lt;T&gt; getQueryResult() = 0;

    private:
        T tObject;
}
</code></pre>
<pre><code class="language-cpp">struct MYOBJECT
{
    int i1;
    int i2;
}

class ABGEL_KLASSE : protected BASISKLASSE&lt;MYOBJECT&gt;
{
    public:

        ABGEL_KLASSE();
        virtual ~ABGEL_KLASSE();

        virtual int setObject(T);
        virtual T getObject();
        virtual std::list&lt;T&gt; getQueryResult();

    private:
        T tObject;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1795149</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1795149</guid><dc:creator><![CDATA[Richard]]></dc:creator><pubDate>Tue, 20 Oct 2009 07:54:41 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign mit Vererbung und Templates on Tue, 20 Oct 2009 08:35:21 GMT]]></title><description><![CDATA[<p>Ich verstehe nicht ganz, was Du eigentlich erreichen willst. Versuch's mal ohne Pseudocode zu beschreiben.</p>
<p>Wozu gibt es denn überhaupt eine Basisklasse und warum verwendest Du &quot;protected inheritance&quot;?</p>
<p>Anmerkungen:<br />
- Es gibt keine virtuellen Elementfunktions-Templates<br />
- Namen, die nur aus Großbuchstaben bestehen, werden üblicherweise nur für Makros und evnetuell auch Konstanzen benutzt.</p>
<p>Gruß,<br />
SP</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1795176</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1795176</guid><dc:creator><![CDATA[Sebastian Pizer]]></dc:creator><pubDate>Tue, 20 Oct 2009 08:35:21 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign mit Vererbung und Templates on Tue, 20 Oct 2009 10:03:49 GMT]]></title><description><![CDATA[<p>Das Großbuchstaben für Makros stehen weiß ich, wollte nur die wichtigen Bestandteile hervorheben.</p>
<p>Jede Klasse steht für eine Tabelle in einer Datenbank und es gibt wiederkehrende set und get- Methoden (z.B. setObject, getObject). Ich möchte eine Basisklasse erzeugen, die den Programmier zwingt in seinen abgeleiteten Klassen bestimmte Methoden zu verwenden (deshalb rein virtuell), die sich jedoch in ihrem Rückgabe- oder Übergabeparameter unterscheiden (in dem Fall tObject).<br />
Der Rück- und Übergabeparametertyp ist mir natürlich noch nicht bekannt. Ich will quasi eine &quot;dynamische&quot; Basisklasse erzeugen, die den Nutzer sowohl eine Schablone (ein template eben) vorgibt, damit er nur noch den spezifischen Typ in seiner abgeleiteten Klasse nachtragen muss und ihn außerdem zwingt einige Methoden zu implementieren, die mit eben diesem Typ arbeiten.</p>
<p>Der Unterschied zu einem normalen Template besteht also darin, dass ich die Klasse nicht instanziere und den Typ angebe, sondern in der Ableitung gern einen Typ vergeben möchte.</p>
<p>Wie gesagt: hab keine Ahnung ob das überhaupt möglich ist...</p>
<p>Wenn nicht, wie würdet ihr das implementieren?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1795222</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1795222</guid><dc:creator><![CDATA[Richard]]></dc:creator><pubDate>Tue, 20 Oct 2009 10:03:49 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign mit Vererbung und Templates on Tue, 20 Oct 2009 12:04:07 GMT]]></title><description><![CDATA[<p>Was spricht gegen sowas?</p>
<pre><code class="language-cpp">template &lt;typename StoredType&gt;
class object_store_class
{
public:
    void set_object(StoredType const&amp; object ) { m_object = object; }
    StoredType&amp; get_object() { return m_object; }
    StoredType const&amp; get_object() const { return m_object; }

private:
    StoredType m_object;
};

// Verwendung:
class int_store_class: public object_store_class&lt;int&gt;
{ };
</code></pre>
<p>Virtuelle Methoden bruachst du da nicht mal.</p>
<p>Gruß<br />
Don06</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1795292</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1795292</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Tue, 20 Oct 2009 12:04:07 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign mit Vererbung und Templates on Fri, 23 Oct 2009 09:11:00 GMT]]></title><description><![CDATA[<p>Vielen Dank für den Tipp, dass hat soweit erstmal funktioniert.</p>
<p>Nun habe ich noch eine weitere Frage bezüglich der Konstruktoren der Basis- und der abgeleiteten Klasse:</p>
<p>Der Header meiner Basisklasse sieht folgendermaßen aus (exemplarisch):</p>
<pre><code class="language-cpp">#ifndef TTABLES_H
#define TTABLES_H

#include &quot;dbSQLITE.h&quot;

#include &lt;list&gt;

template &lt;typename T&gt;
class tTableTemplate
{
    public:
        tTableTemplate();
        ~tTableTemplate();

        /* write into database */
        int dump();
        /* load data from database */
        int load(QString);
        /* get object */
        T&amp; getObject();

        std::list&lt;T&gt; getFirstQueryResult();

    private:
        /* table member */
        T tObject;

        std::list&lt;T&gt; lQueryResult;

        /* database connection */
        SQLITE3 dbHandle;

};

#endif // TTABLES_H
</code></pre>
<p>Die Konstruktoren der Basisklasse und eine exemplarische Funktion aus dem cpp File:</p>
<pre><code class="language-cpp">#include &quot;../header/database/tTableTemplate.h&quot;

template &lt;typename T&gt; tTableTemplate&lt;T&gt;::tTableTemplate()
{ }

template &lt;typename T&gt; tTableTemplate&lt;T&gt;::~tTableTemplate()
{ }

/* write into database */
template &lt;typename T&gt; int tTableTemplate&lt;T&gt;::dump()
{
    int rv = -1;

    return rv;
}
</code></pre>
<p>Der Header der abgeleiteten Klasse:</p>
<pre><code class="language-cpp">#ifndef TPLAYER_H
#define TPLAYER_H

#include &lt;QString&gt;
#include &lt;QDate&gt;
#include &lt;QBool&gt;

#include &quot;tTableTemplate.h&quot;

struct Player
{
    int iID;
    QString sNickname;
    QDate dFirstDate;
    QDate dLastDate;
    bool bBuddy;
};

class tPlayer : public tTableTemplate&lt;Player&gt;
{
    public:
        /* consturctor */
        tPlayer();
        /* destructor */
        ~tPlayer();

    private:
};

#endif // TPLAYER_H
</code></pre>
<p>Und die Implementierung der Konstruktoren:</p>
<pre><code class="language-cpp">#include &quot;../header/database/tPlayer.h&quot;

tPlayer::tPlayer() : tTableTemplate&lt;Player&gt;()
{ }

tPlayer::~tPlayer()
{ }
</code></pre>
<p>Wenn ich den Quellcode so übersetze bekomme ich einen Linkerfehler:</p>
<pre><code>&quot;tTableTemplate&lt;Player&gt;::tTableTemplate()&quot;, referenced from:
tPlayer::tPlayer()in tPlayer.o
tPlayer::tPlayer()in tPlayer.o
&quot;tTableTemplate&lt;Player&gt;::~tTableTemplate()&quot;, referenced from:
tPlayer::~tPlayer()in tPlayer.o
tPlayer::~tPlayer()in tPlayer.o
ld: symbol(s) not found
</code></pre>
<p>Erst wenn ich noch folgende beiden Zeilen in die Implementierung der abgeleiteten Klasse einfüge, compiliert er korrekt:</p>
<pre><code class="language-cpp">template &lt;&gt; tTableTemplate&lt;Player&gt;::tTableTemplate()
{ }

template &lt;&gt; tTableTemplate&lt;Player&gt;::~tTableTemplate()
{ }
</code></pre>
<p>Warum muss ich das manuell einfügen, er müsste doch den Konstruktor und den Destruktor der Basisklasse automatisch und unabhängig vom Typ der abgeleiteten Klasse aufrufen?! Ist das überhaupt korrekt, was ich da als Problemlösung in den Quellcode eingefügt habe?<br />
Muss ich das auch für alle weiteren Funktionen machen? Dann wäre ja irgendwie der Aufwand viel höher als der eigentliche Nutzen!</p>
<p>Gruß,<br />
Richard</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1796914</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1796914</guid><dc:creator><![CDATA[Richard]]></dc:creator><pubDate>Fri, 23 Oct 2009 09:11:00 GMT</pubDate></item><item><title><![CDATA[Reply to Klassendesign mit Vererbung und Templates on Fri, 23 Oct 2009 12:56:39 GMT]]></title><description><![CDATA[<p>Nein, das Problem liegt woanders. Du musst Templates in Headern definieren (nicht nur deklarieren), wenn sie in mehreren Übersetzungseinheiten verwendet werden. Der Grund besteht darin, dass Templates nur <strong>Vorlagen</strong> für Klassen oder Funktionen sind. Der Compiler muss bei der Instanziierung die Templateparameter einsetzen und erstellt so die eigentliche Klasse/Funktion. Da jede Instanziierung wieder ein wenig anders aussehen kann, reicht es nicht, den Code für alle Templateargumente total einmal zu kompilieren (in einer .cpp-Datei). Es gäbe zwar das Schlüsselwort <code>export</code> , das wird aber von so gut wie keinem Compiler unterstützt und hält in anderen Implementierungen (Comeau) auch nicht so viel, wie es verspricht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1797071</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1797071</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Fri, 23 Oct 2009 12:56:39 GMT</pubDate></item></channel></rss>