<?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[pImpl-Idiom und öffentliche Vererbung]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>ich würde gerne &quot;Pointer to implementation&quot; einsetzen. Nun bin ich mir nicht ganz sicher, was ich da mit der Elternklasse anstellen soll.</p>
<p>Derzeit ist die Situation folgende:</p>
<pre><code class="language-cpp">class Parent {
public:
  virtual void foo();
protected:
  Bar* b;
};

class Derived: public Parent {
public:
   virtual void foo() {doSomethingWithBar(b);}
};
</code></pre>
<p>Für derived möchte ich jetzt pimpl benutzen, also</p>
<pre><code class="language-cpp">class DerivedImpl() : public Parent{
public:
   void foo(); {doSomethinghWithBar(b);}
};

class Derived : public Parent {
public:
  virtual void foo() {pimpl_-&gt;foo();}
private:
  DerivedImpl* pimpl_;
};
</code></pre>
<p>Damit ich Derived nachwievor einsetzen kann, muss Derived von Parent erben. Damit aber DerivedImpl b benutzen kann, muss DerivedImpl von Parent erben.</p>
<p>Ist das sinnvoll? Dann habe ich ja zwei &quot;Kopien&quot; von Parent, einmal in Derived und einmal in DerivedImpl, wobei DerivedImpl ja von Derived besessen wird.</p>
<p>Wie geht man damit üblicherweise um?</p>
<p>Gruß,<br />
Philipp</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/272816/pimpl-idiom-und-öffentliche-vererbung</link><generator>RSS for Node</generator><lastBuildDate>Fri, 28 Aug 2026 15:47:27 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/272816.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 25 Aug 2010 17:03:40 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 17:03:40 GMT]]></title><description><![CDATA[<p>Hallo Leute,</p>
<p>ich würde gerne &quot;Pointer to implementation&quot; einsetzen. Nun bin ich mir nicht ganz sicher, was ich da mit der Elternklasse anstellen soll.</p>
<p>Derzeit ist die Situation folgende:</p>
<pre><code class="language-cpp">class Parent {
public:
  virtual void foo();
protected:
  Bar* b;
};

class Derived: public Parent {
public:
   virtual void foo() {doSomethingWithBar(b);}
};
</code></pre>
<p>Für derived möchte ich jetzt pimpl benutzen, also</p>
<pre><code class="language-cpp">class DerivedImpl() : public Parent{
public:
   void foo(); {doSomethinghWithBar(b);}
};

class Derived : public Parent {
public:
  virtual void foo() {pimpl_-&gt;foo();}
private:
  DerivedImpl* pimpl_;
};
</code></pre>
<p>Damit ich Derived nachwievor einsetzen kann, muss Derived von Parent erben. Damit aber DerivedImpl b benutzen kann, muss DerivedImpl von Parent erben.</p>
<p>Ist das sinnvoll? Dann habe ich ja zwei &quot;Kopien&quot; von Parent, einmal in Derived und einmal in DerivedImpl, wobei DerivedImpl ja von Derived besessen wird.</p>
<p>Wie geht man damit üblicherweise um?</p>
<p>Gruß,<br />
Philipp</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1944331</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944331</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Wed, 25 Aug 2010 17:03:40 GMT</pubDate></item><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 18:56:21 GMT]]></title><description><![CDATA[<p>PhilippM schrieb:</p>
<blockquote>
<p>Damit ich Derived nachwievor einsetzen kann, muss Derived von Parent erben.</p>
</blockquote>
<p>Kein Problem...</p>
<p>PhilippM schrieb:</p>
<blockquote>
<p>Damit aber DerivedImpl b benutzen kann, muss DerivedImpl von Parent erben.</p>
</blockquote>
<p>Warum? Warum sollten die Implementationsdetails von der Basisklasse erben müssen?</p>
<p><em>Ich lasse im folgenden, zur Vereinfachung, die in diesem Fall nötigen Destruktoren, Konstruktoren, Kopierkonstruktoren &amp; Zuweisungsoperatoren usw. weg.</em></p>
<pre><code class="language-cpp">// Parent.h
//...
class Parent
{
  public:
    virtual void foo();
  protected:
    Bar* b;
};
</code></pre>
<pre><code class="language-cpp">// Derived.h
//...
class Derived : public Parent
{
  public:
    virtual void foo();
  private:
    struct DerivedImpl;
    DerivedImpl * impl_;
};
</code></pre>
<pre><code class="language-cpp">// Derived.cpp
//...
struct DerivedImpl::Derived
{
    //... (Ich setze hier übrigens selten Methoden ein, sondern halte
    //     meist hier nur die Daten)
};
//...
void Derived::foo()
{
    // Hier irgendwas mit impl anstellen
};
//...
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1944362</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944362</guid><dc:creator><![CDATA[asc]]></dc:creator><pubDate>Wed, 25 Aug 2010 18:56:21 GMT</pubDate></item><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 18:59:02 GMT]]></title><description><![CDATA[<p>asc schrieb:</p>
<blockquote>
<p>Warum? Warum sollten die Implementationsdetails von der Basisklasse erben müssen?</p>
</blockquote>
<p>Weil ich b in der Funktion foo() benutzen muss. Und b ist nunmal im Parent-Teil von Derived gespeichert.</p>
<blockquote>
<pre><code class="language-cpp">// Derived.cpp
//...
struct DerivedImpl::Derived
{
    //... (Ich setze hier übrigens selten Methoden ein, sondern halte
    //     meist hier nur die Daten)
};
</code></pre>
</blockquote>
<p>Du meinst wohl Derived::DerivedImpl, oder?</p>
<p>Philipp</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1944363</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944363</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Wed, 25 Aug 2010 18:59:02 GMT</pubDate></item><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 19:01:50 GMT]]></title><description><![CDATA[<p>Wenn du &quot;Bar&quot; in DerivedImpl benötigst, übergib es doch im Konstruktor von DerivedImpl.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1944364</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944364</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Wed, 25 Aug 2010 19:01:50 GMT</pubDate></item><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 19:13:07 GMT]]></title><description><![CDATA[<p>Im konkreten Fall brauch ich allerdings mehrere Member und Funktionen von Parent. Bei einem einzigen Pointer ließe ich ja noch mit mir reden, aber so ...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1944367</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944367</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Wed, 25 Aug 2010 19:13:07 GMT</pubDate></item><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 20:17:26 GMT]]></title><description><![CDATA[<p>Dann übergib nicht Bar* sondern Derived*, und lass DerivedImpl friend von Derived sein... ABER schön ist das nicht. Design überdenken?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1944381</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944381</guid><dc:creator><![CDATA[[[global:former_user]]]]></dc:creator><pubDate>Wed, 25 Aug 2010 20:17:26 GMT</pubDate></item><item><title><![CDATA[Reply to pImpl-Idiom und öffentliche Vererbung on Wed, 25 Aug 2010 20:26:52 GMT]]></title><description><![CDATA[<p>PhilippM schrieb:</p>
<blockquote>
<p>asc schrieb:</p>
<blockquote>
<p>Warum? Warum sollten die Implementationsdetails von der Basisklasse erben müssen?</p>
</blockquote>
<p>Weil ich b in der Funktion foo() benutzen muss. Und b ist nunmal im Parent-Teil von Derived gespeichert.</p>
</blockquote>
<p>&quot;b&quot; hat im Member-Bereich von Parent gar nix zu suchen! Wenn Pimpl dann bitte richtig! Wenn Derived von Parent erbt, Parent aber nicht gepimplt wird, macht Pimpl bei Derived auch keinen Sinn.<br />
Wenn deine Impl den Member braucht, gib ihn ihm.<br />
Ganz knapp skizziert:</p>
<pre><code class="language-cpp">class Parent {
  struct Impl;
  Impl* impl;
protected:
  Bar* bar() {
    return impl-&gt;b;
  }
};
struct Parent::Impl {
  Bar* b;
};

class Derived : public Parent {
  struct Impl;
  Impl* impl;
public:
  void callImplFoo() {
    impl-&gt;foo(bar());
  }
};

struct Derived::Impl {
  void foo(Bar* b) {
    doSomethingWith(b);
  }
};
</code></pre>
<p>Wenn dich der Parameter in Derived::Impl stört: Du Pimplst, Derived::Impl ist die Implementierung dessen, was sonst im private und/oder protected-Teil steht - das geht eh niemanden was an, Aufurfe kommen nur von Derived. Wenn doch - Pech, musst du den Aufruf auf Derifed::Impl::foo über einen Derived-Methodenaufruf delegieren - wie eben oben gezeigt. Oder protected getter anbieten, oder friend, usw.<br />
Was in den IMPL-Teil rein kommt, kann man sich streiten. Ich leg neben den Membern gern auch mal nützliche Funktionen rein, die sonst niemanden interessieren. Hält die Klassendefinition sauber. Aufrufen tut es aber nur die Klasse die gepimpelt wird.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1944384</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1944384</guid><dc:creator><![CDATA[l&#x27;abra d&#x27;or]]></dc:creator><pubDate>Wed, 25 Aug 2010 20:26:52 GMT</pubDate></item></channel></rss>