<?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[virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich hatte gedacht, dass ich das Konzept der Polymorphie &amp; virtuellen Methoden soweit ganz gut verstanden hätte, stehe aber gerade vor einem Problem, auf das mir so recht keine Lösung einfällt außer Code zu duplizieren.</p>
<p>Also, Basisklasse hat einen Event-Handler f. Maus-Klicks (ist ein Qt-Projekt), der in abgeleiteter Klasse überschrieben werden bzw. erweitert werden soll:</p>
<pre><code class="language-cpp">class NoisyButton : public QPushButton
{
    Q_OBJECT
public:
    NoisyButton(QWidget* parent = 0);

    virtual ~NoisyButton();

    bool isFunctional() const {
        return mFunctional;
    }

[...]
protected slots:
    virtual void mousePressEvent(QMouseEvent*);

[...]
private:
    Sound* mSound;
    bool mFunctional;
};

NoisyButton::mousePressEvent(QMouseEvent* e)
{
    if (!isFunctional())
    {
        mSound-&gt;playback(&quot;disabled.wav&quot;);
        e-&gt;accept();
    }
    else
    {
        e-&gt;ignore();
        QPushButton::mousePressEvent(e);
    }
}
</code></pre>
<p>Jetzt habe ich abgeleitete Klassen SimpleButton, MultiButton, die von NoisyButton erben. Während SimpleButton nichts tut (ist im wesentlichen eine leere Klasse), soll MultiButton eine Mehrfachbelegung des Buttons simulieren (durch mehrfache Klicks wie beim Handy-SMS). Später sollen die Buttons als NoisyButton-Zeiger in einen QVector abgespeichert werden:</p>
<pre><code class="language-cpp">QVector&lt;NoisyButton*&gt; mButtons;
</code></pre>
<pre><code class="language-cpp">class SimpleButton : public NoisyButton
{
    Q_OBJECT
public:
    SimpleButton(QWidget* parent = 0);

    virtual ~SimpleButton();
};

class MultiButton : public NoisyButton
{
    Q_OBJECT
public:
    MultiButton(QWidget* parent = 0);

    void setBtnText(const QStringList&amp; t);

    int interval() const {
        return mClickInterval;
    }

    int acceptInterval() const {
        return mAcceptTimer.interval();
    }

signals:
    void clicked(unsigned count);

public slots:
    void setInterval(int i = 1000);

    void setAcceptInterval(int i = 2000);

protected slots:
    virtual void mousePressEvent(QMouseEvent*);

    void emitAccept();

private:
    unsigned mClicks;
    QStringList mBtnText;
    int mClickInterval;
    QTime mElapsedTime;
    QTime mPressTime;
    QTimer mAcceptInterval;
    int mLastButtonState;
};

MultiButton::MultiButton(QWidget* parent)
    : NoisyButton(parent)
{
    setAcceptInterval();
    setInterval();
    mAcceptTimer.setSingleShot(true);
    connect(&amp;mAcceptTimer, SIGNAL(timeout()), this, SLOT(emitAccept()));
}
void MultiButton::mousePressEvent(QMouseEvent* e)
{
    mLastButtonState = e-&gt;button();

    if (e-&gt;button() &amp; Qt::LeftButton)
    {
        if (mPressTime.elapsed() &lt; mClickInterval)
        {
            mClicks++;
            mClicks = mClicks % mBtnText.size();
        }
        mAcceptTimer.start();
        mPressTime.restart();
    }
}

void MultiButton::emitAccept()
{
    if (mClicks % mBtnText.size() == 0)
        mClicks = mBtnText.size();
    emit clicked(mClicks);
    mAcceptTimer.stop();
    mClicks = 0;
    setText(mBtnText[mClicks % mBtnText.size()]);
}
</code></pre>
<p>Das Problem ist nun, dass ich den MouseHandler-Slot der Basisklasse in der abgeleiteten Klasse ebenfalls ausführen muss, die Funktionalität der virtuellen Funktion aber nur im if-Zweig stattfinden darf.<br />
Wie schaffe ich es, die Basisklassen-Funktionalität in der abgeleiteten Klasse ebenfalls auszuführen, aber eben abhängig vom Zustand von mFunctional? Oder geht das nur mittels Code-Duplizierung, was ja dem Vererbungskonzept widersprechen würde?</p>
<p>Danke für alle Hinweise,<br />
AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/270611/virtuelle-fkt-funktionalität-in-basisklasse-mit-fallunterscheidung</link><generator>RSS for Node</generator><lastBuildDate>Sun, 30 Aug 2026 01:15:40 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/270611.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 15 Jul 2010 09:33:21 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung on Thu, 15 Jul 2010 09:33:21 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich hatte gedacht, dass ich das Konzept der Polymorphie &amp; virtuellen Methoden soweit ganz gut verstanden hätte, stehe aber gerade vor einem Problem, auf das mir so recht keine Lösung einfällt außer Code zu duplizieren.</p>
<p>Also, Basisklasse hat einen Event-Handler f. Maus-Klicks (ist ein Qt-Projekt), der in abgeleiteter Klasse überschrieben werden bzw. erweitert werden soll:</p>
<pre><code class="language-cpp">class NoisyButton : public QPushButton
{
    Q_OBJECT
public:
    NoisyButton(QWidget* parent = 0);

    virtual ~NoisyButton();

    bool isFunctional() const {
        return mFunctional;
    }

[...]
protected slots:
    virtual void mousePressEvent(QMouseEvent*);

[...]
private:
    Sound* mSound;
    bool mFunctional;
};

NoisyButton::mousePressEvent(QMouseEvent* e)
{
    if (!isFunctional())
    {
        mSound-&gt;playback(&quot;disabled.wav&quot;);
        e-&gt;accept();
    }
    else
    {
        e-&gt;ignore();
        QPushButton::mousePressEvent(e);
    }
}
</code></pre>
<p>Jetzt habe ich abgeleitete Klassen SimpleButton, MultiButton, die von NoisyButton erben. Während SimpleButton nichts tut (ist im wesentlichen eine leere Klasse), soll MultiButton eine Mehrfachbelegung des Buttons simulieren (durch mehrfache Klicks wie beim Handy-SMS). Später sollen die Buttons als NoisyButton-Zeiger in einen QVector abgespeichert werden:</p>
<pre><code class="language-cpp">QVector&lt;NoisyButton*&gt; mButtons;
</code></pre>
<pre><code class="language-cpp">class SimpleButton : public NoisyButton
{
    Q_OBJECT
public:
    SimpleButton(QWidget* parent = 0);

    virtual ~SimpleButton();
};

class MultiButton : public NoisyButton
{
    Q_OBJECT
public:
    MultiButton(QWidget* parent = 0);

    void setBtnText(const QStringList&amp; t);

    int interval() const {
        return mClickInterval;
    }

    int acceptInterval() const {
        return mAcceptTimer.interval();
    }

signals:
    void clicked(unsigned count);

public slots:
    void setInterval(int i = 1000);

    void setAcceptInterval(int i = 2000);

protected slots:
    virtual void mousePressEvent(QMouseEvent*);

    void emitAccept();

private:
    unsigned mClicks;
    QStringList mBtnText;
    int mClickInterval;
    QTime mElapsedTime;
    QTime mPressTime;
    QTimer mAcceptInterval;
    int mLastButtonState;
};

MultiButton::MultiButton(QWidget* parent)
    : NoisyButton(parent)
{
    setAcceptInterval();
    setInterval();
    mAcceptTimer.setSingleShot(true);
    connect(&amp;mAcceptTimer, SIGNAL(timeout()), this, SLOT(emitAccept()));
}
void MultiButton::mousePressEvent(QMouseEvent* e)
{
    mLastButtonState = e-&gt;button();

    if (e-&gt;button() &amp; Qt::LeftButton)
    {
        if (mPressTime.elapsed() &lt; mClickInterval)
        {
            mClicks++;
            mClicks = mClicks % mBtnText.size();
        }
        mAcceptTimer.start();
        mPressTime.restart();
    }
}

void MultiButton::emitAccept()
{
    if (mClicks % mBtnText.size() == 0)
        mClicks = mBtnText.size();
    emit clicked(mClicks);
    mAcceptTimer.stop();
    mClicks = 0;
    setText(mBtnText[mClicks % mBtnText.size()]);
}
</code></pre>
<p>Das Problem ist nun, dass ich den MouseHandler-Slot der Basisklasse in der abgeleiteten Klasse ebenfalls ausführen muss, die Funktionalität der virtuellen Funktion aber nur im if-Zweig stattfinden darf.<br />
Wie schaffe ich es, die Basisklassen-Funktionalität in der abgeleiteten Klasse ebenfalls auszuführen, aber eben abhängig vom Zustand von mFunctional? Oder geht das nur mittels Code-Duplizierung, was ja dem Vererbungskonzept widersprechen würde?</p>
<p>Danke für alle Hinweise,<br />
AlGaN</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1926551</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1926551</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Thu, 15 Jul 2010 09:33:21 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung on Thu, 15 Jul 2010 09:43:21 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ohne jetzt auf deinen Code einzugehen:</p>
<blockquote>
<p>Wie schaffe ich es, die Basisklassen-Funktionalität in der abgeleiteten Klasse ebenfalls auszuführen,</p>
</blockquote>
<p>Indem du die Basisklasse direkt ansprichst</p>
<pre><code class="language-cpp">void Derived:fkt()
{
  Base::fkt();
}
</code></pre>
<p>Oder du nutzt das <a href="http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-Virtual_Interface" rel="nofollow">NVI-Idiom</a> und packst den 'immer ausführen' Teil,<br />
in die nicht-virtuelle Funktion.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1926561</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1926561</guid><dc:creator><![CDATA[Jockelx]]></dc:creator><pubDate>Thu, 15 Jul 2010 09:43:21 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung on Thu, 15 Jul 2010 09:43:42 GMT]]></title><description><![CDATA[<p>Ich bin mir nicht ganz sicher, ob ich alles richtig verstanden habe, aber ich versuch es mal:<br />
Wenn du von deinem Vater schwarze Haare erbst und färbst sie blond, ist das schwarz weg. So ist das hier auch: überschreibst du die Methode in der Tochter, wird auch nur die Tochter ausgeführt. Die Mami-Methode ist &quot;weg&quot;. Willst du an die Mami ran, könnte das glaub ich die Tochter in Ihrer Methode über sowas wie parent-&gt;Methode() oder so.<br />
Hab schon länger nix mehr geerbt, müsst ich jetzt nachgucken...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1926562</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1926562</guid><dc:creator><![CDATA[Heimelchen]]></dc:creator><pubDate>Thu, 15 Jul 2010 09:43:42 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung on Thu, 15 Jul 2010 09:45:35 GMT]]></title><description><![CDATA[<p>Und als Ergänzung: mousePressEvent ist kein SLOT!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1926565</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1926565</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Thu, 15 Jul 2010 09:45:35 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung on Thu, 15 Jul 2010 11:23:03 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/23734">@Jockelx</a>: Okay, mein Code ist nicht der beste, vll. hab ich auch einen Design-Fehler drin, mir ist bis jetzt nur keine andere Lösung eingefallen, SimpleButtons und MultiButtons über ein gemeinsames Interface anzusprechen.</p>
<p>Das NVI-Idiom hab ich mir angeschaut, weiß aber nicht, ob es den Code-Bloat rechtfertigt für meinen refactored-Teil der Basisklasse, der ja im wesentlichen nur aus der Fallunterscheidung besteht...</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20104">@l</a>'abra d'or: Okay, war ein Schreibfehler, im originalen Code hab ich den Handler im normalen protected-Abschnitt drin...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1926618</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1926618</guid><dc:creator><![CDATA[AlGaN]]></dc:creator><pubDate>Thu, 15 Jul 2010 11:23:03 GMT</pubDate></item><item><title><![CDATA[Reply to virtuelle Fkt.: Funktionalität in Basisklasse mit Fallunterscheidung on Thu, 15 Jul 2010 15:36:55 GMT]]></title><description><![CDATA[<p>Verwende doch einfach eine neue, eigene virtuelle Funktion:</p>
<pre><code class="language-cpp">class NoisyButton : public QPushButton
{
    Q_OBJECT
public:
    NoisyButton(QWidget* parent = 0);

    virtual ~NoisyButton();

    bool isFunctional() const {
        return mFunctional;
    }

[...]
protected:
    virtual void mousePressEvent(QMouseEvent*);
    virtual void noisyButtonMousePressEvent(QMouseEvent*);

[...]
private:
    Sound* mSound;
    bool mFunctional;
};

void NoisyButton::mousePressEvent(QMouseEvent* e)
{
    if (!isFunctional())
    {
        mSound-&gt;playback(&quot;disabled.wav&quot;);
        e-&gt;accept();
    }
    else
    {
        noisyButtonMousePressEvent(e);
        QPushButton::mousePressEvent(e);
    }
}

// Default-Implementierung, kann von abgeleiteten Klassen überschrieben werden
void NoisyButton::noisyButtonMousePressEvent(QMouseEvent* e)
{
    e-&gt;ignore();
}
</code></pre>
<p>Ob der Aufruf von QPushButton::mousePressEvent(e) und/oder e-&gt;ignore() immer, also für alle von NoisyButton abgeleiteten Controls erfolgen soll, kann ich schwer beurteilen, da ich Qt nicht kenne, und auch nicht genau weiss was du vor hast.<br />
(Alles was immer erfolgen soll/muss sollte in NoisyButton::mousePressEvent passieren, alles was nicht immer erfolgen soll/muss in NoisyButton::noisyButtonMousePressEvent - meine Wahl war mehr oder weniger beliebig)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1926783</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1926783</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 15 Jul 2010 15:36:55 GMT</pubDate></item></channel></rss>