<?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[Polymorpher Zugriff auf Property in Base Class]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich hab wiedermal ein Problem mit polymorphen Funktionen...<br />
Eigentlich hab ich gedacht, ich hätte virtuelle Funktionen verstanden, aber mir scheint doch noch nicht alles klar zu sein... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
<p>Folgende Klassenhierarchie (QPen = Stiftklasse aus Qt):</p>
<pre><code class="language-cpp">class Item
{
public:
    Item( Item* parent = 0);

[...]

    void setPen( const QPen&amp; p );
    const QPen&amp; pen() const
    {
        return mPen;
    }

    void setDefaultPen( const QPen&amp; p );

    virtual void setDefaultPen();

    const QPen&amp; defaultPen() const
    {
        return mDefaultPen;
    }

[...]
private:
    Item* mParent;
    Item* mRoot;
    QPen mPen;
    QPen mDefaultPen;
[...]
};

class Room : public Item
{
public:
    Room( Item* parent = 0);

[...]
};

Item::Item( Item* parent )
  : Item( parent )
{
    setPen( QPen( Qt::NoPen ) );
    [...]
}

void Item::setPen( const QPen&amp; p )
{
    mPen = p;
}

void Item::setDefaultPen( const QPen&amp; p )
{
    mDefaultPen = p;
}

void Item::setDefaultPen()
{
    mPen = mDefaultPen;
}
</code></pre>
<p>Ich will jetzt in abgeleiteten Klassen wie <strong>Room</strong> andere Farben verwenden, also z.B. im Konstruktor:</p>
<pre><code class="language-cpp">Room::Room( Item* parent )
  : Item( parent )
{
    setPen( QPen( QColor( &quot;red&quot; ) ) );
    setDefaultPen( QPen( QColor( &quot;red&quot; ) ) );
    [...]
}
</code></pre>
<p>gleichzeitig muss ich jedoch generisch mit einem Item-Zeiger die Property ändern/abfragen:</p>
<pre><code class="language-cpp">void foobar()
{
    Item* i = getItemfromList();
    // set item pen
    i-&gt;setPen( QColor( &quot;green&quot; ) );
    // tue irgendwas
    i-&gt;setDefaultPen();
}
</code></pre>
<p>Aber da ich nur einen Basiszeiger habe, wird natürlich der Aufruf zu</p>
<pre><code class="language-cpp">i-&gt;Item::setDefaultPen()
</code></pre>
<p>mit den in Item gesetzten Properties für mPen und mDefaultPen. Ich möchte aber den mDefaultPen der <strong>Room</strong>-Klasse setzen.</p>
<p>Wenn o.g. nicht mit Membervariablen möglich ist, muss man es wohl per virtuelle Funktion machen, etwa so:</p>
<pre><code class="language-cpp">class Room : public Item
{
[...]
virtual setDefaultPen()
{
    mPen = QPen( QColor( &quot;red&quot; ) );
}
[...]
};
</code></pre>
<p>Ich hoffe, dass ich jetzt das Ganze nicht zu verwirrend dargestellt habe.</p>
<p>Danke für alle Hinweise,<br />
AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/234496/polymorpher-zugriff-auf-property-in-base-class</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 09:53:05 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/234496.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 18 Feb 2009 16:13:28 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Polymorpher Zugriff auf Property in Base Class on Wed, 18 Feb 2009 16:15:49 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich hab wiedermal ein Problem mit polymorphen Funktionen...<br />
Eigentlich hab ich gedacht, ich hätte virtuelle Funktionen verstanden, aber mir scheint doch noch nicht alles klar zu sein... <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
<p>Folgende Klassenhierarchie (QPen = Stiftklasse aus Qt):</p>
<pre><code class="language-cpp">class Item
{
public:
    Item( Item* parent = 0);

[...]

    void setPen( const QPen&amp; p );
    const QPen&amp; pen() const
    {
        return mPen;
    }

    void setDefaultPen( const QPen&amp; p );

    virtual void setDefaultPen();

    const QPen&amp; defaultPen() const
    {
        return mDefaultPen;
    }

[...]
private:
    Item* mParent;
    Item* mRoot;
    QPen mPen;
    QPen mDefaultPen;
[...]
};

class Room : public Item
{
public:
    Room( Item* parent = 0);

[...]
};

Item::Item( Item* parent )
  : Item( parent )
{
    setPen( QPen( Qt::NoPen ) );
    [...]
}

void Item::setPen( const QPen&amp; p )
{
    mPen = p;
}

void Item::setDefaultPen( const QPen&amp; p )
{
    mDefaultPen = p;
}

void Item::setDefaultPen()
{
    mPen = mDefaultPen;
}
</code></pre>
<p>Ich will jetzt in abgeleiteten Klassen wie <strong>Room</strong> andere Farben verwenden, also z.B. im Konstruktor:</p>
<pre><code class="language-cpp">Room::Room( Item* parent )
  : Item( parent )
{
    setPen( QPen( QColor( &quot;red&quot; ) ) );
    setDefaultPen( QPen( QColor( &quot;red&quot; ) ) );
    [...]
}
</code></pre>
<p>gleichzeitig muss ich jedoch generisch mit einem Item-Zeiger die Property ändern/abfragen:</p>
<pre><code class="language-cpp">void foobar()
{
    Item* i = getItemfromList();
    // set item pen
    i-&gt;setPen( QColor( &quot;green&quot; ) );
    // tue irgendwas
    i-&gt;setDefaultPen();
}
</code></pre>
<p>Aber da ich nur einen Basiszeiger habe, wird natürlich der Aufruf zu</p>
<pre><code class="language-cpp">i-&gt;Item::setDefaultPen()
</code></pre>
<p>mit den in Item gesetzten Properties für mPen und mDefaultPen. Ich möchte aber den mDefaultPen der <strong>Room</strong>-Klasse setzen.</p>
<p>Wenn o.g. nicht mit Membervariablen möglich ist, muss man es wohl per virtuelle Funktion machen, etwa so:</p>
<pre><code class="language-cpp">class Room : public Item
{
[...]
virtual setDefaultPen()
{
    mPen = QPen( QColor( &quot;red&quot; ) );
}
[...]
};
</code></pre>
<p>Ich hoffe, dass ich jetzt das Ganze nicht zu verwirrend dargestellt habe.</p>
<p>Danke für alle Hinweise,<br />
AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665881</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665881</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Wed, 18 Feb 2009 16:15:49 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorpher Zugriff auf Property in Base Class on Wed, 18 Feb 2009 17:01:27 GMT]]></title><description><![CDATA[<p>der defaultPen ist doch in deiner Basisklasse gespeichert, also kann die Basisklasse ihn auch setzen.</p>
<p>Das steht im Room-Konstrutor:</p>
<p>setDefaultPen( QPen( QColor( &quot;red&quot; ) ) );</p>
<p>Damit hast du den gewünschten Wert doch gesetzt. Und in der Basisklasse steht dann nur noch</p>
<pre><code class="language-cpp">void setDefaultPen()
{
    mPen = mDefaultPen;
}
</code></pre>
<p>btw: bei solchen Vererbungsstrukturen, wo du polymorphimus nutzt, solltest du die Destruktoren auch virtuell machen!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665911</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665911</guid><dc:creator><![CDATA[Pellaeon]]></dc:creator><pubDate>Wed, 18 Feb 2009 17:01:27 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorpher Zugriff auf Property in Base Class on Wed, 18 Feb 2009 17:13:35 GMT]]></title><description><![CDATA[<p>AlGaN schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>Noch zwei Hinweise:<br />
1. Keine virtuellen Funktionen direkt oder indirekt im Konstruktor aufrufen (Hierzu sehe ich nicht genügend Code, die Warnung will ich dir aber dennoch geben).<br />
2. Es ist meist besser die Initialisierung von Membern an der Stelle einer Hierarchie zu machen, wo diese deklariert sind. Dies ist keine in Stein gemeißelte Regel, aber erhöht häufig die Wartbarkeit (Reduzierung der Abhängigkeiten). Zumindest würde ich die Initialisierung dann über einen entsprechenden Konstruktor machen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1665921</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1665921</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Wed, 18 Feb 2009 17:13:35 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorpher Zugriff auf Property in Base Class on Thu, 19 Feb 2009 12:13:09 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich hab es jetzt folgendermassen hinbekommen:</p>
<pre><code class="language-cpp">class Item
{
public:
    Item( Item* parent = 0);

    virtual ~Item();

    void setPen( const QPen&amp; p = QPen( Qt::NoPen ), bool rec = false );

    const QPen&amp; pen() const { return mPen; }

    void resetDefaultPen( bool rec = false );

    void setDefaultPen( const QPen&amp; p = QPen( Qt::NoPen ) )
    {
        mDefaultPen = p;
    }

    // has to be virtual
    virtual const QPen defaultPen() const
    {
        return QPen( Qt::NoPen );
    }

[...]

private:
    QPen mPen;
    QPen mDefaultPen;
    QList&lt; Item* &gt; mChildren;

[...]
};

Item::Item( Item* parent )
    : Item( parent )
{
    [...]
    setPen();
    setDefaultPen();
    [...]
}

void Item::setPen(const QPen&amp; p, bool rec)
{
    if ( rec &amp;&amp; !mChildren.isEmpty() )
    {
        foreach ( Item* i, mChildren )
        {
            i-&gt;setPen(p, rec);
        }
    }
    mPen = p;
}

void Item::resetDefaultPen(bool rec)
{
    if (rec &amp;&amp; !mChildren.isEmpty() )
    {
        foreach ( Item* i, mChildren )
        {
            i-&gt;setDefaultPen(rec);
        }
    }
    mPen = defaultPen();
}

class Room : public Item
{
public:
    Room( Item* parent = 0 );

    virtual const QPen defaultPen() const;

[...]
};

Room::Room( Item* parent )
  : Item( parent )
{
    setPen( QPen( QColor( &quot;red&quot; ) ) );
    setDefaultPen( QPen( QColor( &quot;red&quot; ) ) );
[...]
}

const QPen Room::defaultPen() const
{
    return QPen( QColor( &quot;red&quot; ) );
}
</code></pre>
<p>Die Methode <strong>setDefaultPen(const QPen&amp;)</strong> setzt den default Pen eines Items, die Methode <strong>resetDefaultPen(bool)</strong> setzt den Pen eines Items (optional rekursiv f. alle Unter-Items) wieder auf den default Pen.<br />
Aber, um in dieser Methode für jedes Unteritem die spezielle Farbe zu setzen, muss ich dies mit der virtuellen Methode <strong>const QPen defaultPen() const</strong> machen, andernfalls wird ja die Methode der Klasse <strong>Item</strong> aufgerufen, wenn ich nur einen Basisklassenzeiger habe:</p>
<pre><code class="language-cpp">void foobar()
{
    QList&lt; Item* &gt; myItems = getItemList();
    foreach( Item* i, myItems )
    {
        i-&gt;setPen( QColor( &quot;blue&quot; ), true ); // set pen recursive for all subitems
        // tue irgendwas
        [...]
        i-&gt;resetPen( true ); // reset to default pen for all subitems
    }
}
</code></pre>
<p>An dieser Stelle bräuchte ich &quot;virtuelle Memberdaten&quot; für den default Pen?<br />
Oder habe ich irgendwo einen Denkfehler?? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /><br />
Bin für alle Hinweise/Tipps dankbar!</p>
<p>AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1666340</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1666340</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Thu, 19 Feb 2009 12:13:09 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorpher Zugriff auf Property in Base Class on Thu, 19 Feb 2009 19:25:55 GMT]]></title><description><![CDATA[<p>Virtuelle Memberdaten braucht man eigentlich nie. Wenn man in der abgeleiteten Klasse auf Member zugreifen will, die in der Basisklasse noch nicht vorhanden waren, kann man das über eine (möglicherweise rein) virtuelle Funktion umsetzen, die dann je nach Klasse andere Member zurückgibt.</p>
<p>Wenn einem das nicht reicht, ist das Design möglicherweise von Grund auf nicht ganz durchdacht - denn wenn man abgeleitete Klassen gemeinsam über eine Basisklasse durch Polymorphie ansprechen will, sollte man auch gemeinsam vorhandene Operationen ausführen (wobei sich kleine Differenzen in der Funktionalität wie gesagt durch virtuelle Funktionen implementieren lassen).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1666660</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1666660</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Thu, 19 Feb 2009 19:25:55 GMT</pubDate></item><item><title><![CDATA[Reply to Polymorpher Zugriff auf Property in Base Class on Fri, 20 Feb 2009 09:36:47 GMT]]></title><description><![CDATA[<p>Hallo nexus,</p>
<p>danke für Deine Antwort.</p>
<p>Dass das Design nicht ganz durchdacht ist, vermute ich auch (ich habe die Grundstruktur der Item-Hierarchie auch nicht selbst implementiert, urspr. waren alle Farben für die Items als static definiert, was dazu geführt hatte, dass man die Farbe nur global für alle Items setzen konnte)</p>
<p>Trotzdem fällt mir jetzt auf die Schnelle keine andere Lösung als die in meinem letzten Beitrag ein, kann sein, dass da etwas zu umaständlich gelöst wurde, immerhin funktioniert es so <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="🙂"
    /> (das ist im Augenblick das Wichtigste)</p>
<p>Vll. werd ich das nochmal überdenken, wenn ich wieder etwas mehr Zeit habe...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1666913</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1666913</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Fri, 20 Feb 2009 09:36:47 GMT</pubDate></item></channel></rss>