<?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[function pointer auf member-funktionen]]></title><description><![CDATA[<p>Hallo,</p>
<p>habe eine oft diskutierte Frage.</p>
<p>Ich habe eine Klasse, die eine Menge (z.Z. 3) Funktionen besitzt, auf die ich einen Funktionszeiger richten möchte. Ich habe bereits im Forum gelesen, dass man statische Memberfunktionen nehmen kann, auf diese kann man dann die Funktionszeiger richten. Aber wenn man eine Menge Funktionen hat, dann muss man auch eine Menge statische Funktionen dafür schreiben.</p>
<p>Geht das nicht auch einfacher bzw. sinnvoller?</p>
<p>MfG,<br />
Johannes</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/204662/function-pointer-auf-member-funktionen</link><generator>RSS for Node</generator><lastBuildDate>Thu, 08 Oct 2026 18:51:15 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/204662.rss" rel="self" type="application/rss+xml"/><pubDate>Tue, 05 Feb 2008 19:49:07 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to function pointer auf member-funktionen on Tue, 05 Feb 2008 19:49:07 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>habe eine oft diskutierte Frage.</p>
<p>Ich habe eine Klasse, die eine Menge (z.Z. 3) Funktionen besitzt, auf die ich einen Funktionszeiger richten möchte. Ich habe bereits im Forum gelesen, dass man statische Memberfunktionen nehmen kann, auf diese kann man dann die Funktionszeiger richten. Aber wenn man eine Menge Funktionen hat, dann muss man auch eine Menge statische Funktionen dafür schreiben.</p>
<p>Geht das nicht auch einfacher bzw. sinnvoller?</p>
<p>MfG,<br />
Johannes</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450041</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450041</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Tue, 05 Feb 2008 19:49:07 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Tue, 05 Feb 2008 20:08:02 GMT]]></title><description><![CDATA[<p>Nächster Halt <a href="https://www.google.de/search?&amp;q=c%2B%2B%20method%20pointer" rel="nofollow">Google: c++ method pointer</a>.<br />
In Fahrtrichtung links anklicken.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450052</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450052</guid><dc:creator><![CDATA[Zugbegleiter]]></dc:creator><pubDate>Tue, 05 Feb 2008 20:08:02 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Tue, 05 Feb 2008 20:33:51 GMT]]></title><description><![CDATA[<p><a href="http://www.oleeichhorn.com/articles/040617-C++_method_pointer.html" rel="nofollow">http://www.oleeichhorn.com/articles/040617-C++_method_pointer.html</a></p>
<p>Das Problem ist, dass das bei mir nicht funktioniert. Ich arbeite mit pthreads:</p>
<pre><code class="language-cpp">typedef void* (MyServer::*fptr)(void*);
//...
MyServer server1(port); // set up the server
pthread_create(&amp;run_server_thread, NULL, (fptr)&amp;MyServer::run, NULL);
</code></pre>
<p>Es gibt einen compiler-Error:<br />
./myserver.cpp:77: error: cannot convert ‘void* (MyServer::<em>)(void</em>)’ to ‘void* (<em>)(void</em>)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (<em>)(void</em>), void*)’</p>
<p>Der Cast schien mir notwendig, da</p>
<pre><code class="language-cpp">void MyServer::run(void)
</code></pre>
<p>nicht zu dem Funktionspointer eines pthreads passt:</p>
<pre><code class="language-cpp">void *(*start_routine)(void*)
</code></pre>
<p>Und ich weiß nicht, wie pthread_create() den func pointer aufruft... pthread_create() weiß evtl. nicht einmal, welches Objekt ich meine!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450068</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450068</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Tue, 05 Feb 2008 20:33:51 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Tue, 05 Feb 2008 20:43:01 GMT]]></title><description><![CDATA[<p>Grundsätzlich gibts 2 Möglichkeiten:</p>
<ol>
<li>Wenn der Funktionszeiger ein void* Parameter hat kannst du ne Trampolin-Funktion verwenden (s.u.)</li>
<li>Wenn der Funktionszeiger kein geeignetes Parameter hat kannst du nurnoch Thunks verwenden (=ganz furchbar garstig und 0% portierbar).</li>
</ol>
<p>ad 1.:</p>
<pre><code class="language-cpp">void TrampolinFunktion(void* p)
{
    static_cast&lt;MyServer*&gt;(p)-&gt;Run();
}

void foo()
{
    // ...
    MyServer server1;
    pthread_create(&amp;run_server_thread, NULL, TrampolinFunktion, &amp;server1);
    // ...
}
</code></pre>
<p>Mit ein wenig Template-Magic lässt sich das auch generisch für beliebige Klassen und Memberfunktionen implementieren.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450072</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450072</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Tue, 05 Feb 2008 20:43:01 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Tue, 05 Feb 2008 21:08:44 GMT]]></title><description><![CDATA[<p>Zum nachlesen:</p>
<p><a href="http://www.c-plusplus.net/forum/viewtopic-var-t-is-204341-and-highlight-is-funktionszeiger.html" rel="nofollow">http://www.c-plusplus.net/forum/viewtopic-var-t-is-204341-and-highlight-is-funktionszeiger.html</a></p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450086</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450086</guid><dc:creator><![CDATA[drakon]]></dc:creator><pubDate>Tue, 05 Feb 2008 21:08:44 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Wed, 06 Feb 2008 14:57:42 GMT]]></title><description><![CDATA[<p>Das mit den callbacks sieht interessant aus, danke.</p>
<p>Danke auch hustbaer für die Trampolin-Funktion. Wozu braucht man den static_cast? Ginge es hier nicht auch ohne?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450619</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450619</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Wed, 06 Feb 2008 14:57:42 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Wed, 06 Feb 2008 14:59:39 GMT]]></title><description><![CDATA[<p>voidpointer schrieb:</p>
<blockquote>
<p>...Wozu braucht man den static_cast? Ginge es hier nicht auch ohne?</p>
</blockquote>
<p>Nunja ... einen void-Pointer kann man nunmal nicht dereferenzieren (und schon gar nicht mit zu einer &quot;Run()&quot;-Methode.</p>
<p>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450621</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450621</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Wed, 06 Feb 2008 14:59:39 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Wed, 06 Feb 2008 19:03:33 GMT]]></title><description><![CDATA[<p>ach bingo! ok thnx jetzt verstehe ich es <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>sprich: hier würde man diese template-magie anwenden können? (hier ist MyServer eine abgeleitet Klasse von Server, in diesem Fall also keine Templates notwendig)</p>
<p>und das Trampolin lässt noch eine Frage offen: ich brauche eines für jede Funktion in der Klasse!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450770</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450770</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Wed, 06 Feb 2008 19:03:33 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Wed, 06 Feb 2008 22:41:34 GMT]]></title><description><![CDATA[<p>Naja mach es einfach so:</p>
<pre><code class="language-cpp">class foo
{
public:
    virtual void bar();

private:
    static void _bar(void* ptr_inst) { static_cast&lt;foo*&gt;(ptr_inst)-&gt;bar(); }
};
</code></pre>
<pre><code class="language-cpp">foo inst;
pthread_create(&amp;run_server_thread, NULL, &amp;foo::_bar, &amp;inst);
</code></pre>
<p>dann hast de es alles in der Klasse <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="😉"
    /> (Bei WinAPI ist das wohl die einfachste Möglichkeit, alles in eine Klasse packen zu können!)</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1450926</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450926</guid><dc:creator><![CDATA[*D*Evil]]></dc:creator><pubDate>Wed, 06 Feb 2008 22:41:34 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Thu, 07 Feb 2008 00:44:34 GMT]]></title><description><![CDATA[<blockquote>
<p>und das Trampolin lässt noch eine Frage offen: ich brauche eines für jede Funktion in der Klasse!</p>
</blockquote>
<p>Naja, DA z.B. lässt sich die Template Magic anwenden.<br />
Ganz einfach könnte es z.B. so gehen:</p>
<pre><code class="language-cpp">template &lt;class T&gt; void trampoline_function(void* p)
{
    std::auto_ptr&lt;T&gt; t(static_cast&lt;T*&gt;(p));
    (*t)();
}

template &lt;class T&gt; struct member_function_wrapper
{
    member_function_wrapper(T* t, void (T::*f)()) :
        m_t(t), m_f(f)
    {
    }

    void operator()()
    {
       (m_t-&gt;*m_f)();
    }

    T* m_t;
    void (T::*m_f)();
};

template &lt;class T&gt; int my_thread_create(pthread_t* thread, const pthread_attr_t* attr, T&amp; t, void (T::*f)())
{
	std::auto_ptr&lt;member_function_wrapper&lt;ttest&gt; &gt; mfw(new member_function_wrapper&lt;ttest&gt;(t, f));
	int rc = pthread_create(thread, attr, &amp;trampoline_function&lt;member_function_wrapper&lt;ttest&gt; &gt;, mfw.get());
	if (rc)
		return rc; // fehler

	mfw.release(); // gehört jetzt dem thread
	return 0;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1450955</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1450955</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 07 Feb 2008 00:44:34 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Thu, 07 Feb 2008 09:25:31 GMT]]></title><description><![CDATA[<p><img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f44d.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--thumbs_up"
      title=":+1:"
      alt="👍"
    /> <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f60b.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--face_savoring_food"
      title=":yum:"
      alt="😋"
    /> Cool !</p>
<p>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1451041</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1451041</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Thu, 07 Feb 2008 09:25:31 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Thu, 07 Feb 2008 09:29:30 GMT]]></title><description><![CDATA[<p>Vielen Dank für diesen Code! Leider habe ich Schwierigkeiten ihn zu verstehen... der Code muss unbedingt (auch für andere) gut verständlich sein, es soll eine library werden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1451045</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1451045</guid><dc:creator><![CDATA[voidpointer]]></dc:creator><pubDate>Thu, 07 Feb 2008 09:29:30 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Thu, 07 Feb 2008 12:26:09 GMT]]></title><description><![CDATA[<p>Hi,</p>
<p>also ich hab' ihn ja nicht verfasst, aber da &quot;selbst erklären&quot; der wichtigste Schritt beim Lernen ist, versuch ich's mal:</p>
<p>1.) Statt pthread_create(..., void*) wird also my_thread_create(..., <em>pointer_auf_mein_Objekt</em>, <em>member_function_pointer_auf_gewünschte_Memberfunktion</em>) aufgerufen.<br />
Dabei ist der Typ des übergebenen Objekts parametrisierbar (= kann jeder mögliche Typ und trotzdem typsicher sein). Es wird davon ausgegangen, dass die Memberfunktion keinen Rückgabetyp hat und keinen Parameter entgegennimmt - das ist zwar eine Einschränkung, aber nur eine, die man bereits von pthread_create() kennt.</p>
<p>2.) Diese erzeugt ein Objekt vom Typ member_function_wrapper mit folgender Aufgabe:<br />
- die Zeiger auf das Objekt und auf die Memberfunktion bündeln<br />
- die Memberfunktion per operator() aufrufbar zu machen<br />
Vorteil: Man braucht jetzt nur noch EINEN Zeiger (auf member_function_wrapper) und nicht mehr ZWEI (Objekt und Memberfunktion).</p>
<p>3.) Die Trampolin-Funktion hast Du ja schon kennengelernt: Sie castet einen void-Pointer auf einen Objekt-Pointer und ruft eine Memberfunktion davon auf. Damit sie nicht mehr zu wissen braucht, wie die Funktion heißt, bietet der member_function_wrapper sie hinter dem operator() an.</p>
<p>4.) Als nettes Schmankerl wird das member_function_wrapper-Objekt dynamisch erzeugt (damit es nach Ablauf von my_thread_create() nicht vernichtet wird) und &quot;schenkt&quot; es dem neu erzeugten Thread (mittels auto_ptr::release()).</p>
<p>Also Aufruf-Struktur:</p>
<ul>
<li>my_thread_create() =&gt;</li>
<li>pthread_create() =&gt;</li>
<li>trampoline_function() =&gt;</li>
<li>member_function_wrapper::operator() =&gt;</li>
<li><em>Objekt::MemberFunktion</em></li>
</ul>
<p>Ach so, aufgerufen wird das so:</p>
<pre><code class="language-cpp">struct myClass {
   void machWas();
};

int main() {
   std::auto_ptr&lt;myClass&gt; myC(new myClass);
   // pthread-Zeug überspringe ich jetzt mal
   return my_thread_create(..., *(myC.get()), myClass::machWas);
}
</code></pre>
<p>Dabei fällt mir wohl ein Tippfehler bei hustbaers Code auf: in my_thread_create() sollte &quot;ttest&quot; wohl &quot;T&quot; lauten:</p>
<p>hustbaer schrieb:</p>
<blockquote>
<pre><code class="language-cpp">...
template &lt;class T&gt; int my_thread_create(pthread_t* thread, const pthread_attr_t* attr, T&amp; t, void (T::*f)())
{
	std::auto_ptr&lt;member_function_wrapper&lt;ttest&gt; &gt; mfw(new member_function_wrapper&lt;ttest&gt;(t, f));
... &amp;trampoline_function&lt;member_function_wrapper&lt;ttest&gt; &gt;,...
</code></pre>
</blockquote>
<p>=&gt;</p>
<pre><code class="language-cpp">...
template &lt;class T&gt; int my_thread_create(pthread_t* thread, const pthread_attr_t* attr, T&amp; t, void (T::*f)())
{
	std::auto_ptr&lt;member_function_wrapper&lt;T&gt; &gt; mfw(new member_function_wrapper&lt;T&gt;(t, f));
... &amp;trampoline_function&lt;member_function_wrapper&lt;T&gt; &gt;,...
</code></pre>
<p>Gruß,</p>
<p>Simon2.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1451163</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1451163</guid><dc:creator><![CDATA[Simon2]]></dc:creator><pubDate>Thu, 07 Feb 2008 12:26:09 GMT</pubDate></item><item><title><![CDATA[Reply to function pointer auf member-funktionen on Thu, 07 Feb 2008 13:01:56 GMT]]></title><description><![CDATA[<p>Äh.<br />
Ich bin auch was doof <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="🙂"
    /><br />
Die trampoline_function muss natürlich garkein Template sein. Dazu muss man nur den member_function_wrapper von einer abstrakten Basisklasse ableiten und einen virtual call verwenden statt non-virtual...</p>
<p>Naja, egal, falsch isses in der Template Version ja nicht.</p>
<p>Ansonsten: man verwende einfach Boost.Thread für sowas. Wenn man sich den Threading Teil aus irgendeinem Grund doch selbst stricken will kann man immernoch boost::function verwenden - damit kann man dann fast alles als Thread--Funktion verwenden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1451186</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1451186</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Thu, 07 Feb 2008 13:01:56 GMT</pubDate></item></channel></rss>