<?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[auto_ptr und polymorphismus]]></title><description><![CDATA[<p>hallo,</p>
<pre><code class="language-cpp">class eins { ... };
class zwei : public eins { ... };

void test(const std::auto_ptr&lt;eins&gt;&amp; f) { ... }

std::auto_ptr&lt;eins&gt; eins_eins(new eins());
std::auto_ptr&lt;eins&gt; eins_zwei(new zwei());
std::auto_ptr&lt;zwei&gt; zwei_zwei(new zwei());

test(eins_eins);  // ok
test(eins_zwei);  // ok 
test(zwei_zwei);  // error C2664: 'test': Konvertierung des Parameters 1 von 'std::auto_ptr&lt;_Ty&gt;' in 'std::auto_ptr&lt;_Ty&gt; &amp;' nicht möglich
</code></pre>
<p>warum geht das nicht obwohl doch zwei von eins abstammt?<br />
könnte man das mit einem konvertierungsoperator hinkriegen (vorausgesetzt, man könnte auto_ptr beliebig ändern)?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/186582/auto_ptr-und-polymorphismus</link><generator>RSS for Node</generator><lastBuildDate>Thu, 24 Sep 2026 10:34:00 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/186582.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 10 Jul 2007 13:32:36 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 13:32:36 GMT]]></title><description><![CDATA[<p>hallo,</p>
<pre><code class="language-cpp">class eins { ... };
class zwei : public eins { ... };

void test(const std::auto_ptr&lt;eins&gt;&amp; f) { ... }

std::auto_ptr&lt;eins&gt; eins_eins(new eins());
std::auto_ptr&lt;eins&gt; eins_zwei(new zwei());
std::auto_ptr&lt;zwei&gt; zwei_zwei(new zwei());

test(eins_eins);  // ok
test(eins_zwei);  // ok 
test(zwei_zwei);  // error C2664: 'test': Konvertierung des Parameters 1 von 'std::auto_ptr&lt;_Ty&gt;' in 'std::auto_ptr&lt;_Ty&gt; &amp;' nicht möglich
</code></pre>
<p>warum geht das nicht obwohl doch zwei von eins abstammt?<br />
könnte man das mit einem konvertierungsoperator hinkriegen (vorausgesetzt, man könnte auto_ptr beliebig ändern)?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322301</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322301</guid><dc:creator><![CDATA[zzZzz]]></dc:creator><pubDate>Tue, 10 Jul 2007 13:32:36 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 13:36:43 GMT]]></title><description><![CDATA[<p>auto_ptr&lt;eins&gt; und auto_ptr&lt;zwei&gt; sind zwei völlig unabhängige Typen, selbst wenn ihre Template-Parameter miteinander verwandt sind. Durchaus möglich, daß da eine Konvertierung helfen könnte - allerdings müsstest du dafür tief in die Trickkiste greifen, um die Besitz-Semantik von auto_ptr bei dieser Konvertierung nicht zu zerstören.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322307</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322307</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 10 Jul 2007 13:36:43 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 13:44:47 GMT]]></title><description><![CDATA[<p>Übergib doch einfach eine <strong>const eins&amp;</strong>. Die Übergabe einer const Referenz auf einen auto_ptr ist semantisch eh ziemlich fragwürdig. (Bin mir jetzt gerade nicht 100% sicher, ob dann auch die Konvertierung des auto_ptr&lt;zwei&gt; klappt)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322318</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322318</guid><dc:creator><![CDATA[7H3 N4C3R]]></dc:creator><pubDate>Tue, 10 Jul 2007 13:44:47 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 13:45:01 GMT]]></title><description><![CDATA[<p>vorweg: es geht nicht konkret um auto_ptr, es lässt sich damit nur einfacher darstellen. die besitzer-semantik kann man als korrekt umgesetzt annehmen.</p>
<pre><code class="language-cpp">template &lt;typename T&gt;
class auto_ptr {
  public :
     ...
    template &lt;typename D&gt; auto_ptr(const auto_ptr&lt;D&gt;&amp; copy) { ptr=copy.ptr; }
    template &lt;typename D&gt; operator auto_ptr&lt;D&gt;() { return auto_ptr&lt;D&gt;(*this); }

  private :
    T* ptr;
};
</code></pre>
<p>gleicher fehler. kann das so überhaupt gehen?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322320</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322320</guid><dc:creator><![CDATA[zzZZzz]]></dc:creator><pubDate>Tue, 10 Jul 2007 13:45:01 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 13:50:48 GMT]]></title><description><![CDATA[<p>Ja, so könnte man das eventuell ansetzen, aber es reicht eins von beidem - entweder Umwandlungs-Ctor oder -Operator. Wenn du beide anlegst, wird die Umwandlung mehrdeutig und damit nicht mehr möglich (weil der Compiler sonst nicht weiß, ob er <code>smart_ptr&lt;zwei&gt;::operator smart_ptr&lt;eins&gt;()</code> oder <code>smart_ptr&lt;eins&gt;::smart_ptr(const smart_ptr&lt;zwei&gt;)</code> verwenden soll)</p>
<p>(PS: Mit auto_ptr verbindet man fast instinktiv die gleichnamige Standard-Klasse. Wenn du von einer eigenen Pointer-artigen Klasse redest, trifft es der Begriff &quot;Smart-Pointer&quot; besser ;))</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322328</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322328</guid><dc:creator><![CDATA[CStoll]]></dc:creator><pubDate>Tue, 10 Jul 2007 13:50:48 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 14:05:02 GMT]]></title><description><![CDATA[<p>CStoll schrieb:</p>
<blockquote>
<p>(PS: Mit auto_ptr verbindet man fast instinktiv die gleichnamige Standard-Klasse. Wenn du von einer eigenen Pointer-artigen Klasse redest, trifft es der Begriff &quot;Smart-Pointer&quot; besser ;))</p>
</blockquote>
<p>ok, ich wollte nur so wenig wie möglich erklären und auto_ptr verhält sich in der sache exakt so wie mein smartptr.</p>
<p>implizit funktioniert die konvertierung überhaupt nicht, egal ob mit copyc'tor oder ohne.</p>
<p>explizit aufgerufen passiert folgendes:</p>
<pre><code class="language-cpp">// kein copy-c'tor
template &lt;typename D&gt; operator Pointer&lt;D&gt;() { return Pointer&lt;D&gt;(*this); }
...
test(Pointer&lt;eins&gt;(zwei_zwei)); // warning C4717: 'Pointer&lt;zwei&gt;::operator&lt;eins&gt; Pointer&lt;eins&gt;': Rekursiv für alle Steuerelementpfade. Die Funktion verursacht einen Stapelüberlauf zur Laufzeit.
</code></pre>
<p>mit einem copy-c'tor frisst der compiler es, aber beschwert sich dass er nicht auf protected-member von Pointer&lt;zwei&gt; zugreifen darf <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f61e.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--disappointed_face"
      title=":("
      alt="😞"
    /></p>
<p>ich würde auch sehr gerne implizit konvertieren lassen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322354</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322354</guid><dc:creator><![CDATA[zzzZZ]]></dc:creator><pubDate>Tue, 10 Jul 2007 14:05:02 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 19:08:29 GMT]]></title><description><![CDATA[<p>um nochmal darauf zurückzukommen:</p>
<p>7H3 N4C3R schrieb:</p>
<blockquote>
<p>Übergib doch einfach eine <strong>const eins&amp;</strong>.</p>
</blockquote>
<p>ich will aber die verwendung (m)eines smartpointers im verwendeten kontext erzwingen.</p>
<blockquote>
<p>Die Übergabe einer const Referenz auf einen auto_ptr ist semantisch eh ziemlich fragwürdig.</p>
</blockquote>
<p>siehe oben, es geht weniger um einleuchtende semantik als darum den programmierer zu seinem glück zu zwingen. es spricht zumindest nichts offensichtliches dagegen, sofern diese konvertierung sauber hinzukriegen ist.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322593</guid><dc:creator><![CDATA[zzZzz]]></dc:creator><pubDate>Tue, 10 Jul 2007 19:08:29 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 19:42:42 GMT]]></title><description><![CDATA[<blockquote>
<p>ok, ich wollte nur so wenig wie möglich erklären und auto_ptr verhält sich in der sache exakt so wie mein smartptr.</p>
</blockquote>
<p>Nein. Dein Pointer scheint kopierbar zu sein ohne das Original dabei zu verändern. std::auto_ptr ist NICHT kopierbar ohne das Original dabei zu verändern. Das ist ein wichtiger Unterschied und auch der Grund warum &quot;std::auto_ptr&lt;A&gt; const&amp;&quot; nicht implizit in &quot;std::auto_ptr&lt;B&gt; const&amp;&quot; konvertierbar ist, selbst wenn A* implizit in B* konvertierbar ist (upcast).</p>
<blockquote>
<p>implizit funktioniert die konvertierung überhaupt nicht, egal ob mit copyc'tor oder ohne.</p>
</blockquote>
<blockquote>
<p>mit einem copy-c'tor frisst der compiler es, aber beschwert sich dass er nicht auf protected-member von Pointer&lt;zwei&gt; zugreifen darf</p>
</blockquote>
<p>Ein template ctor sollte genug sein damit implizite Konvertierung funktioniert:</p>
<pre><code class="language-cpp">template &lt;class T&gt; class foo
{
public:
    foo(...);

    template &lt;class U&gt; foo(foo&lt;U&gt; const&amp;);
    template &lt;class U&gt; friend class foo; // andere versionen von foo sind friend
private:
    ...
};
</code></pre>
<p>BTW: du solltest wohl eher private verwenden anstelle von protected, mit protected sind die Members im Prinzip für jeden &quot;offen&quot; der nur will (ich muss mir nur eine eigene Klasse von deiner Klasse ableiten und in meiner Klasse z.B. eine static Helperfunktion reinschreiben, dann kann ich über diese Helperfunktion auf alle protected Members deiner Klasse zugreifen)</p>
<p>---</p>
<p>BTW: jemandem etwas aufzwingen zu wollen ist meist ein Fehler. Vor allem wenn du selbst nicht genug über C++ weisst um dieses Problem zu lösen ... naja.<br />
Davon abgesehen kann man generische smart pointer in C++ nicht &quot;safe&quot; machen, man kommt immer an den raw pointer dran, z.B. über operator -&gt;. Ergo kannst du auch niemanden dazu zwingen deine smart pointer Klasse zu verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322609</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322609</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 10 Jul 2007 19:42:42 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 21:31:44 GMT]]></title><description><![CDATA[<p>Über die Implementierung von auto_ptr kann man Bücher schreiben. Fakt ist, dass auto_ptr mit den Vorgaben des Standards ohne Magie niemals im Stande ist, Copy-Initialisierung von einem auto_ptr auf eine abgeleitete Klasse durchzuführen, da steht 8.5/14 4/2.Alt dagegen, es würde stets eine Konvertierungssequenz mit 2 selbstdefinierten Konvertierungsfunkitionen entstehen, was nicht zulässig ist. Eine Variante per const-Overload in Verbindung mit SFINAE wie <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-closed.html#463" rel="nofollow">hier</a> vorgeschlagen, funktioniert nicht, da der const-Overload spezieller ist und auch alle echten const-Objekte konsumiert (Ich frage mich, mit welchen Compilern der Autor das getestat haben will, bei mir funktioniert es jedenfalls nicht). Letzlich benötigen eine Konvertierungssequenz mit nur einer eigenen Konvertierungsfunktion. Der einzige Konstruktor, der darin noch aufgerufen werden darf, ist der Copy-ctor, folglich muss unser Konvertierungsoperator in auto_ptr&amp; konvertieren:</p>
<pre><code class="language-cpp">template&lt;class T&gt;
class auto_ptr
{
public:
    typedef T element_type;

    explicit auto_ptr(T* p = NULL) throw() : p_( p ) {}
    auto_ptr(auto_ptr&amp; other) throw() : p_( other.release() ) {}
    auto_ptr&amp; operator=(auto_ptr&amp; other) throw() { reset( other.release() ); return *this; }
    template&lt;typename U&gt; operator auto_ptr&lt; U &gt;&amp;();
#ifndef _MSC_VER // Workaround wegen Bug in VC bzgl. 12.3.2/1
private:
    struct auto_ptr_ref { auto_ptr* p_; };
public:
    auto_ptr(auto_ptr_ref ref) throw() : p_( ref.p_-&gt;release() ) {}
    auto_ptr&amp; operator=(auto_ptr_ref ref) throw() { reset( ref.p_-&gt;release() ); return *this; }
    operator auto_ptr_ref() { auto_ptr_ref ref = { this }; return ref; }
#endif
    ~auto_ptr() throw() { if ( p_ != NULL ) delete p_; }

    T&amp; operator*() const throw() { return *get(); }
    T* operator-&gt;() const throw() { return get(); }
    T* get() const throw() { return p_; }
    T* release() throw() { T* p = p_; p_ = NULL; return p; }
    void reset(T* p = NULL) throw() { if ( p_ != NULL &amp;&amp; p_ != p ) delete p_; p_ = p; }

private:
    T* p_;
};

struct Base {};
struct Derived : Base {};

typedef auto_ptr&lt; Base &gt; base_ptr;
typedef auto_ptr&lt; Derived &gt; derived_ptr;

void foo()
{
    base_ptr bp;
    const base_ptr cbp;
    derived_ptr dp;
    const derived_ptr cdp;
    base_ptr base_source();
    const base_ptr const_base_source();
    derived_ptr derived_source();
    const derived_ptr const_derived_source();
    void base_sink(base_ptr);
    { base_ptr p = bp; }
    { base_ptr p = dp; }
    base_sink( bp );
    base_sink( dp );
    base_sink(base_source());
    base_sink(derived_source());
#if 0
    { base_ptr p = cbp; }
    { base_ptr p = cdp; }
    base_sink( cbp );
    base_sink( cdp );
    base_sink(const_base_source());
    base_sink(const_derived_source());
#endif
}
</code></pre>
<p>Problematisch ist dabei aber die Implementierung des Konvertierungsoperators - (Typisch Meyers EffC++, Don't try to return a reference when you must return an object) - leider bleibt uns hier nichts anderes übrig. Eine naive Implementation:</p>
<pre><code class="language-cpp">template&lt;typename T&gt; template&lt;typename U&gt; auto_ptr&lt;T&gt;::operator auto_ptr&lt;U&gt;&amp;() throw()
{
    static auto_ptr&lt;U&gt; p;
    p.reset( release() );
    return p;
}
</code></pre>
<p>ist nicht reentrant - selbst mit nur einem Thread knallt es, wenn wir die Funktion mehrfach in einem Ausdruck aufrufen müssen. Wenn wir dynamisch allokieren (mit Flag im auto_ptr, damit im copy-ctor korrekt ein delete ausgeführt wird), riskieren wir exceptions. Möglich wäre auch die Nutzung eine thread-lokalen Ringpuffers, wenn diese groß genug ist,verhindern wir so aliasing-Probleme innerhalb eines Ausdrucks, wirklich schön ist das allerdings auch nicht.<br />
Wirklich gut wird das erst mit C++0x lösbar sein, dann gibt es ja auch move_ptr &amp; Co.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322638</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322638</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Tue, 10 Jul 2007 21:31:44 GMT</pubDate></item><item><title><![CDATA[Reply to auto_ptr und polymorphismus on Tue, 10 Jul 2007 22:52:44 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>BTW: jemandem etwas aufzwingen zu wollen ist meist ein Fehler. Vor allem wenn du selbst nicht genug über C++ weisst um dieses Problem zu lösen ... naja.</p>
</blockquote>
<p>es geht mir darum zur verwendung schlauer statt nackter pointer zu animieren. die schnittstellen müssen an einigen stellen pointer akzeptieren und ich will nackte pointer mit allen mitteln vermeiden.<br />
selbst wenn ich nicht genug über c++ weiß um dieses sehr spezielle problem auf anhieb korrekt und sauber zu lösen, wäre es ziemlich bescheuert deswegen diesen anspruch einfach über board zu werfen. statt dessen lasse ich mir lieber auf die sprünge helfen von leuten, die weniger pragmatisch mit c++ umgehen als ich.</p>
<blockquote>
<p>Davon abgesehen kann man generische smart pointer in C++ nicht &quot;safe&quot; machen, man kommt immer an den raw pointer dran, z.B. über operator -&gt;. Ergo kannst du auch niemanden dazu zwingen deine smart pointer Klasse zu verwenden.</p>
</blockquote>
<p>ich will den pointer ja nicht komplett verstecken. ich will wo immer das möglich ist den jeweiligen programmierer dazu zwingen, über die besitzverhältnisse des pointers nachzudenken. sowas ist hilfreich wenn man mit leuten zusammenarbeitet, die in c denken, sowas ähnliches wie c++ schreiben und wo <em>schnell fertig</em> oberste priorität hat. <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="🙂"
    /></p>
<p>die technischen details lese ich mir ausgeschlafen durch, danke schonmal <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="🙂"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1322680</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1322680</guid><dc:creator><![CDATA[zZzZZ]]></dc:creator><pubDate>Tue, 10 Jul 2007 22:52:44 GMT</pubDate></item></channel></rss>