<?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[shared_ptr braucht vollständige Klassendefinition??]]></title><description><![CDATA[<p>Servus,</p>
<p>ich habe folgende Situation:</p>
<pre><code class="language-cpp">class Derived;
class Base {
public:
    virtual ~Base(){}
    const Derived* foo() const { return foo_; }
    void setFoo(const Derived* foo) { foo_ = foo; }
private:
    const Derived* foo_;
};
class Derived : public Base {
public:
    virtual ~Derived(){}
};
</code></pre>
<p>Einige Base-Objekte halten ein Derived-Objekt, andere dort einfach einen Null-Pointer.<br />
Jetzt wollte ich mir die Mühe sparen, den Copy-Ctor und den Move-Ctor für Base zu schreiben, sondern das vom Compiler erledigen zu lassen. Also wollte ich aus dem dummen Pointer einen shared_ptr machen, und damit definiertes Kopierverhalten und korrekte Destruktion bekommen.</p>
<p>Geht nur leider nicht, da ich folgenden Compilerfehler von gcc vor die Füße geworfen bekomme:</p>
<pre><code>/usr/local/include/boost/checked_delete.hpp:31: error: invalid application of 'sizeof' to incomplete type 'const Derived' 
usr/local/include/boost/checked_delete.hpp:31: error: creating array with negative size ('-0x00000000000000001')
</code></pre>
<p>Ich gehe mal stark davon aus, dass das daran liegt, dass er von Derived nur die Forward-Deklaration und nicht die Definition gesehen hat.</p>
<p>Wie löst man diesen Widerspruch? Ich kann ja Derived nicht vor Base definieren.</p>
<p>Gruß,<br />
Philipp</p>
<p>EDIT: Kopierfehler im ersten Listing. Mit shared_ptr wird daraus:</p>
<pre><code class="language-cpp">class Derived;
class Base {
public:
    virtual ~Base(){}
    const Derived* foo() const { return foo_.get(); }
    void setFoo(const Derived* foo) { foo_.reset(foo); }
private:
    boost::shared_ptr&lt;Derived const&gt; foo_;
};
class Derived : public Base {
public:
    virtual ~Derived(){}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/topic/305335/shared_ptr-braucht-vollständige-klassendefinition</link><generator>RSS for Node</generator><lastBuildDate>Sun, 09 Aug 2026 01:15:14 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/305335.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 26 Jun 2012 15:17:17 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to shared_ptr braucht vollständige Klassendefinition?? on Tue, 26 Jun 2012 15:28:13 GMT]]></title><description><![CDATA[<p>Servus,</p>
<p>ich habe folgende Situation:</p>
<pre><code class="language-cpp">class Derived;
class Base {
public:
    virtual ~Base(){}
    const Derived* foo() const { return foo_; }
    void setFoo(const Derived* foo) { foo_ = foo; }
private:
    const Derived* foo_;
};
class Derived : public Base {
public:
    virtual ~Derived(){}
};
</code></pre>
<p>Einige Base-Objekte halten ein Derived-Objekt, andere dort einfach einen Null-Pointer.<br />
Jetzt wollte ich mir die Mühe sparen, den Copy-Ctor und den Move-Ctor für Base zu schreiben, sondern das vom Compiler erledigen zu lassen. Also wollte ich aus dem dummen Pointer einen shared_ptr machen, und damit definiertes Kopierverhalten und korrekte Destruktion bekommen.</p>
<p>Geht nur leider nicht, da ich folgenden Compilerfehler von gcc vor die Füße geworfen bekomme:</p>
<pre><code>/usr/local/include/boost/checked_delete.hpp:31: error: invalid application of 'sizeof' to incomplete type 'const Derived' 
usr/local/include/boost/checked_delete.hpp:31: error: creating array with negative size ('-0x00000000000000001')
</code></pre>
<p>Ich gehe mal stark davon aus, dass das daran liegt, dass er von Derived nur die Forward-Deklaration und nicht die Definition gesehen hat.</p>
<p>Wie löst man diesen Widerspruch? Ich kann ja Derived nicht vor Base definieren.</p>
<p>Gruß,<br />
Philipp</p>
<p>EDIT: Kopierfehler im ersten Listing. Mit shared_ptr wird daraus:</p>
<pre><code class="language-cpp">class Derived;
class Base {
public:
    virtual ~Base(){}
    const Derived* foo() const { return foo_.get(); }
    void setFoo(const Derived* foo) { foo_.reset(foo); }
private:
    boost::shared_ptr&lt;Derived const&gt; foo_;
};
class Derived : public Base {
public:
    virtual ~Derived(){}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/2227426</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2227426</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Tue, 26 Jun 2012 15:28:13 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr braucht vollständige Klassendefinition?? on Tue, 26 Jun 2012 15:25:25 GMT]]></title><description><![CDATA[<p>Ich sehe hier keinen shared_ptr und Derived ist auch keine abgeleitete Klasse.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2227429</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2227429</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 26 Jun 2012 15:25:25 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr braucht vollständige Klassendefinition?? on Tue, 26 Jun 2012 16:38:24 GMT]]></title><description><![CDATA[<p>Okay, hab das Problem jetzt anders gelöst.<br />
Einsicht: Dass es Base-Objekte gibt, wo foo_ ein Nullpointer ist, und solche, wo foo_ auf eine Derived-Objekt zeigt, ist ein Scheißkonzept. Jetzt gibt's zwei Klassen, und zwar solche ohne foo_ member und solche mit.<br />
Damit entfällt der Bedarf für einen pointer an der Stelle vollkommen.</p>
<p>Was mir allerdings immer noch nicht klar ist, warum boost::shared_ptr die Forward-Deklarierte Klasse angeblich nicht löschen können will.</p>
<p>Denn die Boost Doku sagt ganz klar:</p>
<blockquote>
<p>Note that scoped_ptr requires that T be a complete type at destruction time, but shared_ptr does not.</p>
</blockquote>
<p>Siehe <a href="http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/smart_ptr.htm" rel="nofollow">http://www.boost.org/doc/libs/1_49_0/libs/smart_ptr/smart_ptr.htm</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2227459</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2227459</guid><dc:creator><![CDATA[PhilippM]]></dc:creator><pubDate>Tue, 26 Jun 2012 16:38:24 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr braucht vollständige Klassendefinition?? on Tue, 26 Jun 2012 16:49:51 GMT]]></title><description><![CDATA[<p>Dem Destruktor ist das egal. shared_ptr::reset nicht! Lass dir doch gleich einen shared_ptr geben statt eines rohen Zeigers.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2227462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2227462</guid><dc:creator><![CDATA[krümelkacker]]></dc:creator><pubDate>Tue, 26 Jun 2012 16:49:51 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr braucht vollständige Klassendefinition?? on Tue, 26 Jun 2012 17:01:48 GMT]]></title><description><![CDATA[<p>Bei shared_ptr::reset wird der shared_ptr mit nem neuen Objekt sowie einem neuen Deleter &quot;befüllt&quot;.</p>
<p>Um den Deleter &quot;sicher&quot; erzeugen zu können, zu erzeugen muss die Klasse vollständig definiert sein. Daher verwendet shared_ptr checked_delete, und sicherzustellen dass das auch so ist (C++ erlaubt ein delete auf unvollständige Typen, fordert dann aber dass diese trivial zerstörbar sind, was die meisten Klassen halt nicht sind).</p>
<p>Du kannst aber jederzeit selbst einen eigenen Deleter mitgeben, dann wird dieser verwendet, und shared_ptr moppelt nicht mehr rum wegen Type nicht vollständig.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2227471</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2227471</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 26 Jun 2012 17:01:48 GMT</pubDate></item></channel></rss>