<?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[Pointer auf operator delete[]]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe eine Klasse der ich einen Zeiger auf eine Funktion übergebe, die zur Freigabe (und mehr) eines Member dient.</p>
<pre><code class="language-cpp">template&lt;class Class&gt;
class MyClass
{
	template&lt;class Signature&gt;
	MyClass( 
		Class* 	  Obj,
		Signature DelFunc
	)
	{
		// [...]
	}
};
</code></pre>
<p>So, in der Regel sieht die Funktion wie folgt aus:<br />
void (__cdecl*)(void*)</p>
<p>Da dies jedoch auch anders sein kann, muss ich auch diesen Fall handeln. Oben stehender Code funktioniert auch für alle möglichen Fälle:</p>
<pre><code class="language-cpp">void Func1(void*);
void Func2(Class*);
Class* Func3(void*);
Class* Func4(Class*);
</code></pre>
<p>Dummerweiße jedoch nicht für den operator delete. Ich bekomme vom Compiler immer die Meldung:</p>
<pre><code>MyClass&lt;Class&gt;::MyClass : function does not take 2 arguments.
</code></pre>
<p>Normalerweiße werden Objekte einer internen Datenbank hier gehandelt, im Zweifel muss jedoch einfach nur Delete aufgerufen werden. Wo liegt das Problem?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/263042/pointer-auf-operator-delete</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 01:28:46 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/263042.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 15 Mar 2010 10:18:43 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 10:18:55 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe eine Klasse der ich einen Zeiger auf eine Funktion übergebe, die zur Freigabe (und mehr) eines Member dient.</p>
<pre><code class="language-cpp">template&lt;class Class&gt;
class MyClass
{
	template&lt;class Signature&gt;
	MyClass( 
		Class* 	  Obj,
		Signature DelFunc
	)
	{
		// [...]
	}
};
</code></pre>
<p>So, in der Regel sieht die Funktion wie folgt aus:<br />
void (__cdecl*)(void*)</p>
<p>Da dies jedoch auch anders sein kann, muss ich auch diesen Fall handeln. Oben stehender Code funktioniert auch für alle möglichen Fälle:</p>
<pre><code class="language-cpp">void Func1(void*);
void Func2(Class*);
Class* Func3(void*);
Class* Func4(Class*);
</code></pre>
<p>Dummerweiße jedoch nicht für den operator delete. Ich bekomme vom Compiler immer die Meldung:</p>
<pre><code>MyClass&lt;Class&gt;::MyClass : function does not take 2 arguments.
</code></pre>
<p>Normalerweiße werden Objekte einer internen Datenbank hier gehandelt, im Zweifel muss jedoch einfach nur Delete aufgerufen werden. Wo liegt das Problem?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869152</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869152</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 10:18:55 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 10:55:50 GMT]]></title><description><![CDATA[<p>Wie rufst du denn delete auf?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869165</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869165</guid><dc:creator><![CDATA[Michael E.]]></dc:creator><pubDate>Mon, 15 Mar 2010 10:55:50 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 11:16:04 GMT]]></title><description><![CDATA[<p>Michael E. schrieb:</p>
<blockquote>
<p>Wie rufst du denn delete auf?</p>
</blockquote>
<p>Im Destruktor. I.d.R. wird nicht einfach der Operator delete, sondern eine umfangreichere delete Funktion aufgerufen:</p>
<pre><code class="language-cpp">virtual ~MyClass()
{
	this-&gt;Delete(this-&gt;obj);
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1869179</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869179</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 11:16:04 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 11:23:06 GMT]]></title><description><![CDATA[<p>Und was ist <code>Delete</code> für ein Objekt? Wie übergibst du den <code>operator delete</code> ?</p>
<p>Ganz allgemein:<br />
Wieso machst du nicht noch einen Konstruktor, wo keine Delete-Funktion übergeben wird und das <code>Delete</code> Objekt auf nullptr oder sonst einen ungültigen Wert setzt? Im Destruktur prüfst du dann die Gültigkeit und falls es ungültig ist, löschst du es mit <code>delete</code> . Dürfte auch für den Anwender angenehmer sein, als dass er den <code>operator delete</code> übergeben muss.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869180</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869180</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Mar 2010 11:23:06 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 13:28:04 GMT]]></title><description><![CDATA[<p>Das ganze sehe so aus. Den Operator kann man doch auch als default Parameter übergeben:</p>
<pre><code class="language-cpp">template&lt;class Class&gt;
class MyClass
{
private:
	Class*	obj;
	void (__cdecl *Delete)(Class*);

public:
	template&lt;class Signature&gt;
	MyClass( 
		Class* 	  Obj,
		Signature DelFunc = ::operator delete
	)
	{
		this-&gt;Delete = DelFunc;
	}	

	virtual ~MyClass()
	{
		this-&gt;Delete(this-&gt;obj);
	}
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1869189</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869189</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 13:28:04 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 11:43:35 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Das ganze sehe so aus. Den Operator kann man doch auch als default Parameter übergeben:</p>
</blockquote>
<p>Du verpasst damit aber die Möglichkeit, dass per <code>delete</code> auch standardmässig der <code>operator delete</code> der Klasse selbst aufgerufen wird, falls einer definiert ist <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Zudem bin ich gerade nicht ganz sicher darüber, wie <code>operator delete</code> von der Standardbibliothek definiert sein muss. Auch gibt es mehrere davon. Mal schauen, ob da jemand anderes gerade noch zusätzliche Informationen auswendig kennt <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>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869198</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869198</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Mar 2010 11:43:35 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 12:00:43 GMT]]></title><description><![CDATA[<p>Zumindest bei <a href="http://msdn.microsoft.com/en-us/library/248aa748%28VS.80%29.aspx" rel="nofollow">MSDN</a> ist nur die Rede von einer Überladung.</p>
<p>Wo liegt denn grundsätzlich das Problem? Der Operator delete ist folgendermaßen forward deklariert:</p>
<pre><code class="language-cpp">void operator delete(void*);
</code></pre>
<p>Warum nimmt er diese Funktion nicht, void Func(void*) aber schon?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869210</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869210</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 12:00:43 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 12:16:41 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Zumindest bei <a href="http://msdn.microsoft.com/en-us/library/248aa748.aspx" rel="nofollow">MSDN</a> ist nur die Rede von einer Überladung.</p>
</blockquote>
<p>Wo bitte soll dies im Artikel stehen? Im Standard steht es zudem anders.</p>
<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Wo liegt denn grundsätzlich das Problem? Der Operator delete ist folgendermaßen forward deklariert:</p>
</blockquote>
<p>Forward deklariert? Hast du dies selber gemacht? Eine Deklaration von <code>operator delete</code> ist implizit immer in jeder TU schon vorhanden!</p>
<p>Wieso willst du diesen unnötigen, komplizierten und beschränkteren Weg gehen? Wie ich schon sagte, wenn du <code>delete</code> aufrufst, hast du mehr Standardverhalten, als wenn du probierst diese Funktion irgendwie zu speichern.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869222</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869222</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Mar 2010 12:16:41 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 12:25:22 GMT]]></title><description><![CDATA[<p>Im Endeffekt möchte ich doch nur wissen, wo der große Unterschied zwischen</p>
<p>void operator delete(void*) und<br />
void Func(void*)</p>
<p>ist, da letzteres funktioniert und operator delete nicht. Mehr nicht. Ist doch legitim wisse zu wollen, woher der Compiler-Fehler kommt.<br />
Ich kann das ganze natürlich auch anders lösen, aber interessieren tut mich die Fehler-Ursache schon.</p>
<p>Zudem weiß ich nicht, wie ich bei deiner Version dann explizit den operator delete oder den operator delete[] aufrufen soll.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869226</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869226</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 12:25:22 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 12:39:03 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>..., aber interessieren tut mich die Fehler-Ursache schon.</p>
</blockquote>
<p>Kannst du ein vollständig, kompilierbares und kleines Beispielprogramm zeigen, welches den Fehler reproduziert? Wenn diese Vorlesung weiterhin so stink langweilig ist, dann kann ich mir dies in den nächsten Stunden noch anschauen <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869232</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869232</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Mar 2010 12:39:03 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 13:01:00 GMT]]></title><description><![CDATA[<p>Übrigens ist <code>operator delete</code> lediglich eine Speicherdeallokationsfunktion, es wird nicht der Destruktor aufgerufen. <code>operator delete(x)</code> ist nicht dasselbe wie <code>delete x</code> .</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869243</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869243</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 15 Mar 2010 13:01:00 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 13:50:23 GMT]]></title><description><![CDATA[<p>Okay, soweit verunstaltet, dass es fast wie eine SmartPointer Implementation ausschaut ;-). Naja, so ähnlich ist es ja auch fast.<br />
Hab's mal heruntergebrochen auf nen ganz normalen int Typen. Die Datenbankobjekte sagen euch sowieso nichts, da firmenintern.</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;

using std::cout;

template&lt;class Class&gt;
class MyClass
{
private:
	Class* obj;
	void (__cdecl *const Delete)(Class*);

public:
	template&lt;class Signature&gt;
	MyClass(Class* Obj, Signature DelFunc) : Delete((void (__cdecl*)(Class*))DelFunc), obj(Obj) {}	

	virtual ~MyClass() {
		this-&gt;Delete(this-&gt;obj);
	}
};

void Delete1(void* memory)
{
	delete memory;
}

void Delete2(int* memory)
{
	delete memory;
}

int* Delete3(void* memory)
{
	delete memory;
	return 0;
}

int* Delete4(int* memory)
{
	delete memory;
	return 0;
}

int main()
{
	MyClass&lt;int&gt; myc1(new int, Delete1);
	MyClass&lt;int&gt; myc2(new int, Delete2);
	MyClass&lt;int&gt; myc3(new int, Delete3);
	MyClass&lt;int&gt; myc4(new int, Delete4);

	// Error	1	error C2660: 'MyClass&lt;Class&gt;::MyClass' : function does not take 2 arguments
	MyClass&lt;int&gt; myc5(new int, operator delete);		

	return 0;
}
</code></pre>
<p>Bashar schrieb:</p>
<blockquote>
<p>Übrigens ist <code>operator delete</code> lediglich eine Speicherdeallokationsfunktion, es wird nicht der Destruktor aufgerufen. <code>operator delete(x)</code> ist nicht dasselbe wie <code>delete x</code> .</p>
</blockquote>
<p>Ist hier auch nicht anders gewünscht. Aber mal was anderes: Was passiert eigentlich wenn man delete[] für ein &quot;nicht-array&quot; aufruft bzw. sollte man dann nicht immer delete[] aufrufen, wenn man nicht weiß, ob es sich um ein array handelt?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869275</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869275</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 13:50:23 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 14:58:05 GMT]]></title><description><![CDATA[<p>Undefiniertes Verhalten, was sonst <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/1869341</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869341</guid><dc:creator><![CDATA[Bashar]]></dc:creator><pubDate>Mon, 15 Mar 2010 14:58:05 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 15:11:23 GMT]]></title><description><![CDATA[<p>Bashar schrieb:</p>
<blockquote>
<p>Undefiniertes Verhalten, was sonst <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>
</blockquote>
<p>Ich habe mich damit noch nicht beschäftigt, aber delete[] muss ja irgendwie feststellen, wie viele Bytes es denn freigeben muss.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869345</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869345</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Mon, 15 Mar 2010 15:11:23 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Mon, 15 Mar 2010 16:39:12 GMT]]></title><description><![CDATA[<p>Professor wollte dann doch noch, dass wir nicht gelangweilt herumsitzen. Haben wohl zuviele in den Laptop getippt, statt aufgepasst <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20434">@FrEEzE2046</a>,<br />
Was soll das bitte für ein Cast in deinem Konstruktor sein? Das ist ja sowas von abartig! Dadurch kann man wunderschönes undefiniertes Verhalten auslösen und der Kompiler winkt alles brav durch. Nimm diesen Cast da weg!<br />
Und nun wirst du sicher sagen: &quot;Aber dann kommen Kompilerfehler!&quot;<br />
So löst man aber keine Kompilerfehler und erst recht nicht diese. Ich empfehle dir, dass du mal <code>boost::function</code> , bzw. <code>std::tr1::function</code> anschaust. Das ist der bessere und saubere Weg.</p>
<p>Wenn du das entsprechend korrigiert hast, wirst du übrigens auch sehen, dass der Kompiler meckert, weil <code>operator delete</code> ein überladener Operator ist. Genau wie ich es gedacht habe <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>..., aber delete[] muss ja irgendwie feststellen, wie viele Bytes es denn freigeben muss.</p>
</blockquote>
<p>Wie <code>delete[]</code> den Speicher freigeben muss, gibt der Standard keine Vorgaben. Es ist schlicht und einfach kompilerabhängig. Und daher ist der Aufruf von <code>delete[]</code> , auf einen Speicherbereich der per <code>new</code> geholt wurde, undefiniert. Gleiches gilt im umgekehrten Fall ( <code>delete</code> und <code>new[]</code> ). Da bringt es nichts lange rumzuphilosophieren, wie ein Betriebsystem oder Kompiler dies nun tut. Sobald du sowas einsetzt, hast du undefiniertes Verhalten. Es mag auf diesem System mit diesem Kompiler funktionieren und beim nächsten Wechsel von einer dieser Variablen kracht das ganze Programm oder es gibt ein Speicherfehler, der aber dann wo völlig anders auftritt. Undefinierte Fehler zu beheben ist etwas vom mühsamsten, daher gleich erst gar nicht erlauben, dass solche Fehler auftreten könnten.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869406</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869406</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Mon, 15 Mar 2010 16:39:12 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Tue, 16 Mar 2010 07:46:30 GMT]]></title><description><![CDATA[<p>Ich wollte eigentlich nicht extra eine Functor-Klasse bemühen, da dass aus meiner Sicht hier nicht nötig ist.</p>
<p>Der Cast ist widerlich, ich weiß. Aber warum stellst dass ein so großes Problem dar?</p>
<p>Im Endeffekt bleibt die Funktion doch immer wieder gleich. Wir haben:</p>
<pre><code class="language-cpp">TypA Function(TypB);
</code></pre>
<p>Das bringe ich immer in die Form:</p>
<pre><code class="language-cpp">void Function(Class*);
</code></pre>
<p>So. Da in den Klammern immer ein Pointer und damit entsprechend der Wortbreite des Professors, viele Byte auf den Stack gepushed werden sehe ich hier keinen Grund für undefiniertes Verhalten. Das bestätigt auch das Assembly-Listing.</p>
<p>Schlussendlich ist auf unterster Ebene doch egal, um was für einen &quot;Typ&quot; es sich hier handelt, so lange die Größe gleich bleibt.</p>
<p>Jede Funktion liegt an einer speziellen Adresse die der Kompiler kennen muss. Er weiß nun auch wie viele Byte er auf den Stack zu pushen hat. Und dass der Rückgabewert nun void ist ... na und? Dass bedeutet nur, dass ich den Wert aus dem eax Register nicht als return value benutze.</p>
<p>Ich sehe da nicht wirklich das Problem.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869630</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869630</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 16 Mar 2010 07:46:30 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Tue, 16 Mar 2010 07:41:06 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Ich wollte eigentlich nicht extra eine Functor-Klasse bemühen, da dass aus meiner Sicht hier nicht nötig ist.</p>
<p>Der Cast ist widerlich, ich weiß. Aber warum stellst dass ein so großes Problem dar?</p>
</blockquote>
<p>Sorry wenn ich grad mal völlig off topic bin, aber hier stellt was anderes ein großes Problem dar: <a href="http://www.dass-das.de/" rel="nofollow">http://www.dass-das.de/</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869638</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869638</guid><dc:creator><![CDATA[pumuckl]]></dc:creator><pubDate>Tue, 16 Mar 2010 07:41:06 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Tue, 16 Mar 2010 09:02:28 GMT]]></title><description><![CDATA[<p>Bisschen undefiniertes Verhalten gefälligst?</p>
<pre><code class="language-cpp">template&lt;class Class&gt; 
class MyClass 
{ 
private: 
    Class* obj; 
    void (__cdecl *const Delete)(Class*); 

public: 
    template&lt;class Signature&gt; 
    MyClass(Class* Obj, Signature DelFunc) : Delete((void (__cdecl*)(Class*))DelFunc), obj(Obj) {}    

    virtual ~MyClass() { 
        this-&gt;Delete(this-&gt;obj); 
    } 
}; 

void foo(short, char, int)
{
}

void bar(MyClass&lt;int&gt;, MyClass&lt;void&gt;)
{
}

int main() 
{
    // Mal schauen ...
    MyClass&lt;int&gt; myc1(new int, &amp;foo); 
    MyClass&lt;int&gt; myc2(new int, &amp;bar);

    // Oder vielleicht?
    MyClass&lt;int&gt; myc3(new int, 'c'); 
    MyClass&lt;int&gt; myc4(new int, &quot;error&quot;);
    MyClass&lt;int&gt; myc5(new int, 2343577); 

    // Und solchen Zucker kann man auch erzeugen.
    MyClass&lt;int&gt; myc6(new int, &amp;myc1);

    return 0; 
}
</code></pre>
<p>Es kompiliert, man kann es ausführen, allerdings besteht die Möglichkeit, dass man damit den Weltuntergang heraufbeschwört <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Du umgehst eben jegliche Typsicherheit. Das ist ja auch ein Grund, wieso man C Cast oder auch <code>reinterpret_cast</code> vermeiden sollte.</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869661</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869661</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 16 Mar 2010 09:02:28 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Tue, 16 Mar 2010 10:51:45 GMT]]></title><description><![CDATA[<p>ah,<br />
jetzt verstehen wir uns. Wenn ich natürlich gar keine Funktion, sondern irgengwas anderes, übergebe kommt natürlich irgendetwas undefiniertes heraus.</p>
<p>Lässt sich aber eigentlich leicht umgehen:</p>
<pre><code class="language-cpp">template&lt;class Signature&gt;
class IsFunction;

template&lt;typename R, typename P0&gt;
class IsFunction&lt;R (__cdecl*)(P0)&gt; {};

// [...]

// error C2079: 'MyClass' uses undefined class
MyClass&lt;int&gt; myc5(new int, &quot;error&quot;);
</code></pre>
<p>EDIT:<br />
Natürlich kann man auch noch prüfen, ob es sich wirklich um einen Pointer handelt:</p>
<pre><code class="language-cpp">// zur Laufzeit:

template&lt;class Signature&gt;
struct FunctionTypeExtractor;

template&lt;typename R, typename P0&gt;
struct FunctionTypeExtractor&lt;R (__cdecl*)(P0)&gt; 
{
	enum {ParamSize = sizeof(P0)};
};

template&lt;class Class&gt;
class MyClass
{
public:
	template&lt;class Signature&gt;
	MyClass(Class* Obj, Signature DelFunc) : obj(Obj) 
	{
		if( FunctionTypeExtractor&lt;Signature&gt;::ParamSize == sizeof(void*) )
		{
			this-&gt;Delete = (void (__cdecl*)(Class*))DelFunc;
		}
		else
			throw std::exception(&quot;error&quot;); 
	}	
};
</code></pre>
<pre><code class="language-cpp">// Zur Kompilierzeit:

template&lt;unsigned n&gt;
class SIZE_OF_POINTER;

template&lt;&gt;
class SIZE_OF_POINTER&lt;sizeof(void*)&gt; {};

template&lt;class Signature&gt;
struct FunctionTypeExtractor;

template&lt;typename R, typename P0&gt;
struct FunctionTypeExtractor&lt;R (__cdecl*)(P0)&gt; 
{
	SIZE_OF_POINTER&lt;sizeof(P0)&gt; dummy;
};

template&lt;class Class&gt;
class MyClass
{
public:
	template&lt;class Signature&gt;
	MyClass(Class* Obj, Signature DelFunc) : obj(Obj) 
	{
		FunctionTypeExtractor&lt;Signature&gt; dummy;
		this-&gt;Delete = (void (__cdecl*)(Class*))DelFunc;
	}	
};
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1869692</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869692</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 16 Mar 2010 10:51:45 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Tue, 16 Mar 2010 11:23:41 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/20434">@FrEEzE2046</a>,<br />
Und du bist immer noch der Meinung, dass du keine &quot;Funktor-Klasse&quot; benötigst? Du zerstörst die Typsicherheit und probierst sie dann irgendwie halb über Templatemataprogrammierung wieder einzuführen. Sogar teilweise über Laufzeitfehler statt Kompilerfehler und ich hoffe doch, dass du mit mir übereinstimmst, dass Kompilerfehler viel besser sind als Laufzeitfehler. All das zeigt doch schon, dass da etwas nicht stimmt.</p>
<p>Zudem auch mit deinen bisherigen Sicherheiten, kann man immer noch Unsinn bauen:</p>
<pre><code class="language-cpp">void foo(int) {}
void bar(char*) {}

// ...

MyClass&lt;int&gt; a(new int, &amp;foo);
MyClass&lt;int&gt; b(new int, &amp;bar);
</code></pre>
<p>Unsinn bedeutet hier, dass man versehentlich falsche Funktion übergeben könnte. Durch einen Schreibfehler, eine Unachtsamkeit oder sonstwas. Was das am Ende heissen wird, ist völlig frei. Womöglich löschst du tatsächlich die Datenbank mit so einem Fehler, weil durch den Schreibfehler eine Funktion zum löschen der Datenbank aufgerufen wurde und zufälligerweise der richtige Parameter übergeben wurde.</p>
<p>Und nicht zuletzt zeigt auch dein Kompilerfehler-Problem, wegen welchem du diesen Thread eröffnet hast, dass dein Cast irgendwelchen Unsinn produziert. Als Templateparameter kann nämlich eine überladene Funktion aktzeptiert werden, nur kann man sie halt nicht in einem solchen Funktionszeiger ablegen. Der Kompiler ist dann anscheinend nicht mal mehr in der Lage eine sinnvolle Fehlermeldung zu generieren, bei einem solch dreckigen Cast <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
<p>Was man auch nicht vergessen sollte, bzw. was auch noch ein grosser Vorteil von z.B. <code>boost::function</code> , bzw. <code>std::tr1::function</code> , ist, dass man auch Funktoren übergeben kann. Man hat eine deutlich grössere Freiheit und trotzdem volle Typsicherheit.</p>
<p>Braucht es noch mehr, um dich von diesem falschen Weg abzubringen? Oder willst du wirklich lieber ins Verderben rennen? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1869741</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869741</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Tue, 16 Mar 2010 11:23:41 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Tue, 16 Mar 2010 11:49:52 GMT]]></title><description><![CDATA[<p>Danke für deine Antwort, wegen Kompiler- o. Laufzeitfehler brauchen wir uns nicht zu unterhalten, aber ansonsten muss ich dir weiterhin widersprechen.</p>
<p>Eine falsche Funktion, die in Wirklichkeit etwas ganz anderes löscht oder tut, kann ich auch einer Functor-Klasse übergeben. Wo siehst du da den Schutz? Verschreiben kann ich mich überall.</p>
<p>Zweitens spielt es auch keine Rolle, ob eine überladene Funktion übergeben wird.<br />
1. Beschwert sich der Kompiler dann über ein doppeldeutiges Symbol.<br />
2. Möchte ich aber unbedingt eine überladene Funktion übergeben, kann ich ja wieder casten:</p>
<pre><code class="language-cpp">void func(int*) {}
void func(int*, char) {}

MyClass&lt;int&gt; myc5(new int, (void (*)(int*))func);
</code></pre>
<p>Ich denke, dass auf diese Art die Typsicherheit gewährleistet ist.</p>
<p>EDIT:<br />
ganz nebenbei kann auch std::tr1::function nicht zwischen überladenen Funktionen unterscheiden:</p>
<pre><code class="language-cpp">// Error	1	error C2664: 'std::tr1::function&lt;_Fty&gt;::function(const std::tr1::function&lt;_Fty&gt; &amp;)' : cannot convert parameter 1 from 'overloaded-function' to 'const std::tr1::function&lt;_Fty&gt; &amp;'
std::tr1::function&lt;void (int*)&gt; myfunc(func);
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1869768</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1869768</guid><dc:creator><![CDATA[FrEEzE2046]]></dc:creator><pubDate>Tue, 16 Mar 2010 11:49:52 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Wed, 17 Mar 2010 08:55:24 GMT]]></title><description><![CDATA[<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Eine falsche Funktion, die in Wirklichkeit etwas ganz anderes löscht oder tut, kann ich auch einer Functor-Klasse übergeben. Wo siehst du da den Schutz? Verschreiben kann ich mich überall.</p>
</blockquote>
<p>Es geht nicht um einen absoluten Schutz, sondern einer Verminderung der Fehlerquote. Wenn man <code>MyClass&lt;int&gt;</code> erstellt, dann sollte man auch nur Funktionen übergeben können, welche einen <code>int*</code> oder <code>void*</code> erwartet. Bei deiner Version kann man aber halt auch ein <code>char*</code> übergeben, oder sonst irgendeinen Zeiger. Das ist mit <code>boost::function</code> oder <code>std::tr1::function</code> nicht möglich und es ist somit eine Reduzierung der Fehlerwahrscheinlichkeit vorhanden.<br />
Und das Geile am Ganzen ist, dass du noch zusätzlich weitere Verwendungsmöglichkeiten bekommst.</p>
<p>Und nun die Frage an dich: Wo siehst du denn bitte die Nachteile, dass du dich so dagegen sträubst und es lieber über wilde und unsaubere Casts machen möchtest?</p>
<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>2. Möchte ich aber unbedingt eine überladene Funktion übergeben, kann ich ja wieder casten:</p>
<pre><code class="language-cpp">void func(int*) {}
void func(int*, char) {}

MyClass&lt;int&gt; myc5(new int, (void (*)(int*))func);
</code></pre>
</blockquote>
<p>Ich wage sehr stark zu bezweifeln, dass dies gültiges ISO C++ ist. Der Cast darf man sicher machen, ob es allerdings garantiert ist, dass dann die richtige Funktion aufgerufen wird, wage ich wirklich stark zu bezweifeln. Kompilerfehler löst man nicht einfach durch Casts, erst recht nicht durch C Cast. Damit handelst du dir nur Fehler ein.</p>
<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>Ich denke, dass auf diese Art die Typsicherheit gewährleistet ist.</p>
</blockquote>
<p>Wie ich schon mehrmals aufgezeigt habe, ist sie das nicht.</p>
<p>FrEEzE2046 schrieb:</p>
<blockquote>
<p>ganz nebenbei kann auch std::tr1::function nicht zwischen überladenen Funktionen unterscheiden:</p>
</blockquote>
<p>Habe ich schon weiter vorne geschrieben. Weshalb ich ja auch empfohlen habe, lieber ein Standardverhalten einzuführen und einfach <code>delete</code> aufzurufen.</p>
<p>Die Frage steht oben, aber ich schreibe sie vielleicht besser nochmals hin:<br />
Wieso willst du nicht <code>std::tr1::function</code> verwenden? Was ist dein Beweggrund?</p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1870185</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1870185</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Wed, 17 Mar 2010 08:55:24 GMT</pubDate></item><item><title><![CDATA[Reply to Pointer auf operator delete[] on Wed, 17 Mar 2010 16:15:26 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>FrEEzE2046 schrieb:</p>
<blockquote>
<pre><code class="language-cpp">void func(int*) {}
void func(int*, char) {}

MyClass&lt;int&gt; myc5(new int, (void (*)(int*))func);
</code></pre>
</blockquote>
<p>Ich wage sehr stark zu bezweifeln, dass dies gültiges ISO C++ ist. Der Cast darf man sicher machen, ob es allerdings garantiert ist, dass dann die richtige Funktion aufgerufen wird, wage ich wirklich stark zu bezweifeln. Kompilerfehler löst man nicht einfach durch Casts, erst recht nicht durch C Cast. Damit handelst du dir nur Fehler ein.</p>
</blockquote>
<p>Das Beispiel ist korrekt, allerdings ist der C-cast abzulehnen. ist func nähmlich ausnahmsweise nicht überladen, hat aber den falschen Typ, wird hier ein Funktionszeiger des falschen Typs erstellt, und MyClass&lt;int&gt; weiß das nat. nicht. Richtig ist in solchen Fällen ein static_cast.</p>
<pre><code class="language-cpp">MyClass&lt;int&gt; myc5(new int, static_cast&lt;void(&amp;)(int*)&gt;(func));
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1870457</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1870457</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Wed, 17 Mar 2010 16:15:26 GMT</pubDate></item></channel></rss>