<?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[Zeiger schützen]]></title><description><![CDATA[<p>Abend,</p>
<p>ich habe folgende Klasse:</p>
<pre><code class="language-cpp">class Root {
private:	
   Renderer*	renderer;
   Timer*	timer;

   std::vector&lt;Renderer*&gt; rendererList;
   std::vector&lt;Timer*&gt;    timerList;

public:
	Root() { renderer = new Renderer; timer = new Timer; }
	~Root();

	Renderer*   getRenderer() const { return renderer; }
	Timer*	    getTimer() const { return timer; }

        Renderer*   createRenderer() { 
           Renderer* r = new Renderer;
           rendererList.push_back(r);
           return r;
        }
};
</code></pre>
<p>Die Klasse Foo &quot;kapselt&quot; also verschiedene Zeiger, bietet Getter auf die Zeiger und erzeugt auch neue Instanzen. Die Klasse Foo merkt sich in vector's was sie angelegt hat und im Destructor von Foo wird der ganze Speicher wieder freigegeben.</p>
<p>Nur eine Sache gefällt mir nicht: Durch die get() und create() Methoden kriegt der Anwender Zugriff auf den echten Zeiger. Wenn er auf den Rückgabewert delete aufruft, löscht er den Speicher, ohne das Foo das bemerkt.</p>
<p>Wie kann ich das verhindern und das Design verbessern?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/246402/zeiger-schützen</link><generator>RSS for Node</generator><lastBuildDate>Fri, 18 Sep 2026 04:35:48 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/246402.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 27 Jul 2009 18:12:18 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:12:18 GMT]]></title><description><![CDATA[<p>Abend,</p>
<p>ich habe folgende Klasse:</p>
<pre><code class="language-cpp">class Root {
private:	
   Renderer*	renderer;
   Timer*	timer;

   std::vector&lt;Renderer*&gt; rendererList;
   std::vector&lt;Timer*&gt;    timerList;

public:
	Root() { renderer = new Renderer; timer = new Timer; }
	~Root();

	Renderer*   getRenderer() const { return renderer; }
	Timer*	    getTimer() const { return timer; }

        Renderer*   createRenderer() { 
           Renderer* r = new Renderer;
           rendererList.push_back(r);
           return r;
        }
};
</code></pre>
<p>Die Klasse Foo &quot;kapselt&quot; also verschiedene Zeiger, bietet Getter auf die Zeiger und erzeugt auch neue Instanzen. Die Klasse Foo merkt sich in vector's was sie angelegt hat und im Destructor von Foo wird der ganze Speicher wieder freigegeben.</p>
<p>Nur eine Sache gefällt mir nicht: Durch die get() und create() Methoden kriegt der Anwender Zugriff auf den echten Zeiger. Wenn er auf den Rückgabewert delete aufruft, löscht er den Speicher, ohne das Foo das bemerkt.</p>
<p>Wie kann ich das verhindern und das Design verbessern?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750450</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750450</guid><dc:creator><![CDATA[maarp]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:12:18 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:17:52 GMT]]></title><description><![CDATA[<p>const oder Referenzen.</p>
<p>Oder: Was soll denn Root fuer Funktionalitaet kapseln? Ich sehe sie irgendwie als unnoetig an.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750452</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750452</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:17:52 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:16:54 GMT]]></title><description><![CDATA[<p>Geht zum Beispiel so: Einen Zeiger-Proxy rausgeben, der öffentlich nur -&gt; kann.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750453</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750453</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:16:54 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:17:25 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>const oder Referenzen.</p>
</blockquote>
<p>const hilft gegen delete?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750455</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750455</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:17:25 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:37:36 GMT]]></title><description><![CDATA[<p>volkard schrieb:</p>
<blockquote>
<p>knivil schrieb:</p>
<blockquote>
<p>const oder Referenzen.</p>
</blockquote>
<p>const hilft gegen delete?</p>
</blockquote>
<p>k.A. kann aber grad nicht testen ... Waere aber bloed, wenn nicht. (so rein vom logischen, da ja beim Loeschen der Destruktor aufgerufen wird)</p>
<p>edit: Ich lese gerade ... operator delete private machen.</p>
<p>Symmetrieprinzip: Wenn deine Root-Klasse eine create-Methode anbietet, sollte sie auch eine destroy-Methode anbieten. Jaja ich reite wohl in letzter Zeit viel zu sehr drauf rum. Alternativ kannst du im Destruktor von Renderer es so einrichten, dass er sich automatisch aus der Liste entfernt (was aber eher unschoen ist).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750457</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750457</guid><dc:creator><![CDATA[knivil]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:37:36 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:30:32 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>volkard schrieb:</p>
<blockquote>
<p>knivil schrieb:</p>
<blockquote>
<p>const oder Referenzen.</p>
</blockquote>
<p>const hilft gegen delete?</p>
</blockquote>
<p>k.A. kann aber grad nicht testen ... Waere aber bloed, wenn nicht. (so rein vom logischen, da ja beim Loeschen der Destruktor aufgerufen wird)</p>
</blockquote>
<p>const hilft nicht gegen delete().</p>
<p>Stefan.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750462</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750462</guid><dc:creator><![CDATA[DStefan]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:30:32 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:50:13 GMT]]></title><description><![CDATA[<p>Warum eigentlich?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750476</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750476</guid><dc:creator><![CDATA[Why]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:50:13 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 18:54:32 GMT]]></title><description><![CDATA[<p>Why schrieb:</p>
<blockquote>
<p>Warum eigentlich?</p>
</blockquote>
<pre><code class="language-cpp">const Foo* foo = new Foo(&quot;Bar&quot;);
delete foo;
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1750480</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750480</guid><dc:creator><![CDATA[Don06]]></dc:creator><pubDate>Mon, 27 Jul 2009 18:54:32 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 19:21:24 GMT]]></title><description><![CDATA[<p>knivil schrieb:</p>
<blockquote>
<p>edit: Ich lese gerade ... operator delete private machen.</p>
</blockquote>
<p>Nette Idee. Oder gleich den ganzen Destruktor, vielleicht haben diese Objekte auch nichts auf dem Stack zu suchen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750503</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750503</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 27 Jul 2009 19:21:24 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 21:36:21 GMT]]></title><description><![CDATA[<p>maarp schrieb:</p>
<blockquote>
<p>Nur eine Sache gefällt mir nicht: Durch die get() und create() Methoden kriegt der Anwender Zugriff auf den echten Zeiger. Wenn er auf den Rückgabewert delete aufruft, löscht er den Speicher, ohne das Foo das bemerkt.</p>
</blockquote>
<p>Okay, aber macht man sowas?</p>
<pre><code class="language-cpp">delete root.getRenderer();
</code></pre>
<p>Wenn man den Zeiger selbst oft abspeichert und weiterverwendet, kann das vielleicht eher passieren. Dann frage ich mich aber, ob der Benutzer sich wirklich so häufig mit rohen Zeigern rumschlagen muss. Und bei Factory-Methoden, die Zeiger zurückgeben, sollte Konvention sein, dass es ein Analogon zur Freigabe gibt. Insofern hat knivil schon Recht.</p>
<p>Klar ist es nicht grundsätzlich schlecht, böse Aktionen zu verhindern. Aber man muss sich auch überlegen, wo die Grenze ist, alles verhindern wird man nie können.</p>
<p>Gibst du deine Zeiger im Container auch wieder mal frei (also der Speicher dahinter)? Rohe Zeiger in Containern, die Objekte besitzen, finde ich etwas heikel. Vielleicht stellt Boosts PointerContainer-Bibliothek ein Alternative für dich dar (nur mal als Einwurf am Rande, ich will dir nicht zu gross im Design rumpfuschen)...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750589</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750589</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 27 Jul 2009 21:36:21 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 21:40:58 GMT]]></title><description><![CDATA[<p>Nexus schrieb:</p>
<blockquote>
<p>Gibst du deine Zeiger im Container auch wieder mal frei (also der Speicher dahinter)? Rohe Zeiger in Containern, die Objekte besitzen, finde ich etwas heikel. Vielleicht stellt Boosts PointerContainer-Bibliothek ein Alternative für dich dar (nur mal als Einwurf am Rande, ich will dir nicht zu gross im Design rumpfuschen)...</p>
</blockquote>
<p>Ich habe eigentlich kein schlechtes Gewissen dabei, wenn das der DTor der besitzenden Klasse, in diesem Fall Root das macht.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750590</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750590</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 27 Jul 2009 21:40:58 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 21:49:53 GMT]]></title><description><![CDATA[<p>Also ich will den Code unbedingt simpel halten und nicht &quot;überdesigned&quot;.<br />
Der Dtor von Root gibt den ganzen mit new angelegten Speicher wieder frei.</p>
<p>Würde es nicht reichen, wenn die Klassen der zurückgelieferten Objekte (also Timer, Renderer etc), den Destructor und Constructor private machen und Root als friend deklarieren? Dann kann nur Root Objekte erzeugen/zerstören</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750593</guid><dc:creator><![CDATA[maarp]]></dc:creator><pubDate>Mon, 27 Jul 2009 21:49:53 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 21:51:18 GMT]]></title><description><![CDATA[<p>@ volkard:<br />
Naja, solange man nicht viel mit dem Container anstellt, kann auch nicht viel passieren. Ich sagte das vor allem, weil es hier bereits einige Leute gab, die entweder gar nicht wussten, dass man nicht nur Zeiger in Containern speichern kann, oder sich nicht im geringsten die Konsequenzen ausgemalt haben. Ein <code>delete</code> bei einem <code>erase()</code> geht schnell mal vergessen. Oder ein Container ist schnell kopiert, und der Zugriff kann eventuell sogar lange gut gehen.</p>
<p>Ausserdem finde ich auch, man nutzt einen wichtigen Teil der Container nicht oder nur teilweise, wenn man wieder manuelle Speicherverwaltung hat. Ich habe das jedenfalls nicht so gern. Mein Einwand ist auch eher präventiv gemeint, eben weil recht viele Probleme entstehen können, an die man anfangs gar nicht denkt. Denn solange etwas gut geht und man sich keiner Problematik bewusst ist, wird man es weiter anwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750594</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750594</guid><dc:creator><![CDATA[Nexus]]></dc:creator><pubDate>Mon, 27 Jul 2009 21:51:18 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Mon, 27 Jul 2009 21:58:46 GMT]]></title><description><![CDATA[<p>maarp schrieb:</p>
<blockquote>
<p>Also ich will den Code unbedingt simpel halten und nicht &quot;überdesigned&quot;.<br />
Der Dtor von Root gibt den ganzen mit new angelegten Speicher wieder frei.</p>
<p>Würde es nicht reichen, wenn die Klassen der zurückgelieferten Objekte (also Timer, Renderer etc), den Destructor und Constructor private machen und Root als friend deklarieren? Dann kann nur Root Objekte erzeugen/zerstören</p>
</blockquote>
<p>Und Kopierkonstruktor und Zuweisungsoperator? Und Konstruktor und Zuweisungsoperator von Root auch private machen, sonst spielt man in der Tat mit Nexus' Gefahr.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750597</guid><dc:creator><![CDATA[volkard]]></dc:creator><pubDate>Mon, 27 Jul 2009 21:58:46 GMT</pubDate></item><item><title><![CDATA[Reply to Zeiger schützen on Tue, 28 Jul 2009 06:53:10 GMT]]></title><description><![CDATA[<p>Ähm, alles schön und gut. Aber wer sowas (in der Art) schon gesehen hat, versucht nicht mehr verkrampft, jede Verwendung von Rückgabewerten abzusichern...</p>
<pre><code class="language-cpp">int&amp; get()
{
    static int val = 10;
    return val;
}

int main()
{
    delete &amp;get();
}
</code></pre>
<p>Ist natürlich Noob. Aber für einen etwas erfahreneren Programmierer ist auch klar, dass wenn in der Doku steht &quot;returned Pointer is ownd by the producing class&quot; dass ich den nicht löschen sollte...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1750654</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1750654</guid><dc:creator><![CDATA[gremler]]></dc:creator><pubDate>Tue, 28 Jul 2009 06:53:10 GMT</pubDate></item></channel></rss>