]> git.llucax.com Git - z.facultad/75.42/plaqui.git/blobdiff - docs/oo_callbacks_cpp/oo_callbacks_cpp.html
arregle un poquito la and
[z.facultad/75.42/plaqui.git] / docs / oo_callbacks_cpp / oo_callbacks_cpp.html
index 5eaa82847aad989630f0c9a8dd873a2fb1f467d3..839e513b5f99e0c413a1f8d1504c026584eb6f8a 100644 (file)
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
-<!-- saved from url=(0045)http://cscene.org/topics/misc/cs7-04.xml.html -->\r
-<HTML><HEAD><TITLE>Callbacks in C++: The OO Way</TITLE>\r
-<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type><LINK \r
-href="default.css" rel=stylesheet \r
-type=text/css>\r
-<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>\r
-<BODY>\r
-<TABLE width="100%">\r
-  <TBODY>\r
-  <TR>\r
-    <TD><A href="http://cscene.org/"><IMG alt="cscene logo" border=0 \r
-      class=logo height=52 src="logo.gif" \r
-      width=120></A></TD>\r
-    <TD align=middle width="100%"><A \r
-      href="http://cscene.org/index.html">C-Scene</A> <A \r
-      href="http://cscene.org/issues.html">Issues 1..9</A> <A \r
-      href="http://cscene.org/bios.html">Authors</A> <BR><A \r
-      href="http://cscene.org/topics/algo.xml.html">Algorithms</A> <A \r
-      href="http://cscene.org/topics/books.xml.html">Books</A> <A \r
-      href="http://cscene.org/topics/patterns.xml.html">Patterns</A> <A \r
-      href="http://cscene.org/topics/graphics.xml.html">Graphics</A> <A \r
-      href="http://cscene.org/topics/misc.xml.html">Miscellaneous</A> <A \r
-      href="http://cscene.org/topics/unix.xml.html">UNIX</A> <A \r
-      href="http://cscene.org/topics/web.xml.html">Web &amp; XML</A> <A \r
-      href="http://cscene.org/topics/windows.xml.html">Windows</A> <BR><A \r
-      href="http://cscene.org/feedback.html">Feedback</A> <A \r
-      href="http://cscene.org/faqs.html">FAQs</A> <A \r
-      href="http://cscene.org/changes.html">Changes</A> <A \r
-      href="http://cscene.org/submit.html">Submissions</A> </TD>\r
-    <TD>\r
-      <FORM action=http://www.google.com/search method=get><INPUT name=hl \r
-      type=hidden value=en><INPUT name=safe type=hidden value=off><INPUT \r
-      name=domains type=hidden value=cscene.org><INPUT name=sitesearch \r
-      type=hidden value=cscene.org><INPUT maxLength=256 name=q size=31><INPUT name=btnG type=submit value=Search></FORM></TD></TR></TBODY></TABLE>\r
-<H1 class=s1>Callbacks in C++: The OO Way</H1>\r
-<DIV class=toc>\r
-<H2 class=s2 id=N1698364>Content</H2>\r
-<OL>\r
-  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N7895983">What are \r
-  Callbacks?</A>\r
-  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N310499">A simple \r
-  Thread class</A>\r
-  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N7751758">Thread \r
-  implementation</A>\r
-  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N3038356">A real \r
-  Thread class</A></LI></OL></DIV>\r
-<DIV class=article>\r
-<P>by <I>Jürgen Hermann</I><BR>last updated <I>2001/08/02</I> (version \r
-<I>1.1.1.1</I>)<BR>also available as <A \r
-href="http://cscene.org/topics/misc/cs7-04.xml.txt">XML</A></P>\r
-<DIV class=s2>\r
-<H2 class=s2 id=N7895983>What are Callbacks?</H2>\r
-<P>Many operating systems and other subsystems (like GUI libraries) feature a \r
-special type of hook into those systems, named callbacks or callback functions. \r
-Upon initialization or by calling an API function you pass pointers to the \r
-callback into the subsystem, for later use. The problem with those functions is, \r
-since these subsystems are nowadays not yet OO, that they have no notion of what \r
-an object is. So if you want to have a <EM>callback object&nbsp;</EM> instead of \r
-a mere function, some OO magic is called for.</P>\r
-<P>As an example, consider the <CODE>BeginThread</CODE> API that many OSes have \r
-in a quite similar form; we assume that it takes a pointer to the function that \r
-provides the actual code for the newly created thread plus a <EM>data \r
-pointer&nbsp;</EM> that is passed to that function as a startup parameter. Thus, \r
-we end up with <CODE>BeginThread (void (*thread_func) (void*), void* \r
-startup_data)</CODE>. Now let's make a <CODE>Thread</CODE> class of \r
-that.</P></DIV>\r
-<DIV class=s2>\r
-<H2 class=s2 id=N310499>A simple Thread class</H2>\r
-<P>What we want to have is an ABC (abstract base class) that you can inherit \r
-from, creating specialized thread classes and in turn thread objects (i.e. \r
-actual threads). The code of the thread is located in a <EM>pure \r
-virtual&nbsp;</EM> function <CODE>code</CODE> that is provided by the inherited \r
-class. <CODE>code</CODE> is then similar to the <CODE>thread_func</CODE> \r
-parameter of the <CODE>BeginThread</CODE> call, but is a full-blown member \r
-function, not just a C function. So, we get this interface for the \r
-<CODE>Thread</CODE> class:</P><PRE class=source>class Thread {\r
-public:\r
-    virtual ~Thread();\r
-    void run();\r
-\r
-protected:\r
-    Thread();\r
-    virtual void code() = 0;\r
-\r
-private:\r
-    int running;\r
-\r
-    static void dispatch(void* thread_obj);\r
-};\r
-</PRE>\r
-<P>This might seem quite unusual to you (like having a protected constructor), \r
-but things will be explained in due course.</P></DIV>\r
-<DIV class=s2>\r
-<H2 class=s2 id=N7751758>Thread implementation</H2>\r
-<P>When we put the thread concept into a class, we have to consider lifetime. A \r
-thread exists as long as the thread function does not return, thus the object \r
-has to have the same lifetime. Because of this, an <CODE>auto</CODE> thread \r
-object does not make much sense; we insure that every thread object exists on \r
-the heap by making the ctor protected and providing a static factory method \r
-<CODE>create</CODE> for thread objects in each derived class:</P><PRE class=source>Thread::Thread() \r
-    : running(0) \r
-{\r
-}\r
-\r
-DerivedThread&amp; DerivedThread::create()\r
-{\r
-    return *new DerivedThread;\r
-}\r
-</PRE>\r
-<P><CODE>create</CODE> has to be added to every inherited class, returning an \r
-object of that class.</P>\r
-<P>Next, we need a <CODE>run</CODE> method that actually starts the thread. This \r
-can't be done in the ctor: when <CODE>code</CODE> would be registered as a \r
-thread of execution in the <EM>base class&nbsp;</EM> ctor, the superclass would \r
-not yet be fully created and calling <CODE>code</CODE> would be quite invalid \r
-and dangerous. <CODE>run</CODE> does its job by registering the \r
-<CODE>dispatch</CODE> function as a thread, giving that thread the object \r
-pointer as a startup parameter; since <CODE>dispatch</CODE> is static, it has a \r
-prototype that matches the <CODE>void(*)(void*)</CODE> parameter of \r
-<CODE>BeginThread</CODE>.</P><PRE class=source>void Thread::run()\r
-{\r
-    // Don't start two threads on the same object\r
-    if (running) return;\r
-\r
-    // Create an OS thread, using the static callback\r
-    BeginThread(Thread::dispatch, this);\r
-    running = 1;\r
-}\r
-</PRE>\r
-<P>So finally, <CODE>dispatch</CODE> is called and performs the step from a \r
-procedural callback to the callback object:</P><PRE class=source>void Thread::dispatch(void* thread_obj)\r
-{\r
-    // Call the actual OO thread code\r
-    ((Thread*)thread_obj)-&gt;code();\r
-\r
-    // After code() returns, kill the thread object\r
-    delete (Thread*)thread_obj;\r
-}\r
-</PRE></DIV>\r
-<DIV class=s2>\r
-<H2 class=s2 id=N3038356>A real Thread class</H2>\r
-<P>A real-world thread class has to consider a few things we have ignored here. \r
-These things include: </P>\r
-<OL class=userlist>\r
-  <LI>more access to the thread data, like a method giving the thread ID. \r
-  <LI>a method for killing the thread, including the deletion of the thread \r
-  object. </LI></OL>\r
-<P>Developed and tested on Windows NT, this is the <A \r
-href="http://cscene.org/archives/callback.cpp.txt">source</A> for a little \r
-example program that implements the above in the real world. If you run it, you \r
-get something similar to the following output:</P><PRE class=source>[\cscene\callback]callback\r
-Started thread #80 for dice1\r
-Started thread #84 for dice2\r
-dice1 rolled 1\r
-dice2 rolled 1\r
-dice2 rolled 3\r
-dice1 rolled 1\r
-dice2 rolled 4\r
-dice1 rolled 6\r
-dice1 rolled 3\r
-dice2 rolled 3\r
-dice1 rolled 1\r
-dice1 rolled 4\r
-dice2 rolled 4\r
-dice2 rolled 3\r
-dice1 rolled 1\r
-dice2 rolled 6\r
-dice1 rolled 2\r
-dice2 rolled 2\r
-dice1 rolled 1\r
-dice2 rolled 4\r
-dice2 rolled 1\r
-dice1 rolled 4\r
-dice1 rolled 5\r
-dice2 rolled 1\r
-dice1 rolled 3\r
-dice2 rolled 3\r
-dice1 rolled 2\r
-dice1 rolled 6\r
-dice2 rolled 2\r
-dice1 rolled 1\r
-dice2 rolled 3\r
-dice1 rolled 4\r
-dice1 rolled 5\r
-dice2 rolled 3\r
-dice2 rolled 6\r
-dice1 rolled 4\r
-</PRE>\r
-<P>Have fun!</P></DIV>\r
-<P><SMALL><EM>This article is Copyright © 1997-98 by Jürgen Hermann<BR>and \r
-Copyright © 1999 by C-Scene. All Rights Reserved. </EM></SMALL></P></DIV>\r
-<DIV class=lastwords>\r
-<HR>\r
-Copyright © 1997-2000 by C-Scene. All Rights Reserved.<BR><BR>Part of the \r
-graphics and stylesheets used to generate this site are<BR>Copyright © 1999-2000 \r
-by Apache Software Foundation. </DIV></BODY></HTML>\r
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!-- saved from url=(0045)http://cscene.org/topics/misc/cs7-04.xml.html -->
+<HTML><HEAD><TITLE>Callbacks in C++: The OO Way</TITLE>
+<META content="text/html; charset=iso-8859-1" http-equiv=Content-Type><LINK 
+href="default.css" rel=stylesheet 
+type=text/css>
+<META content="MSHTML 5.00.2920.0" name=GENERATOR></HEAD>
+<BODY>
+<TABLE width="100%">
+  <TBODY>
+  <TR>
+    <TD><A href="http://cscene.org/"><IMG alt="cscene logo" border=0 
+      class=logo height=52 src="logo.gif" 
+      width=120></A></TD>
+    <TD align=middle width="100%"><A 
+      href="http://cscene.org/index.html">C-Scene</A> <A 
+      href="http://cscene.org/issues.html">Issues 1..9</A> <A 
+      href="http://cscene.org/bios.html">Authors</A> <BR><A 
+      href="http://cscene.org/topics/algo.xml.html">Algorithms</A> <A 
+      href="http://cscene.org/topics/books.xml.html">Books</A> <A 
+      href="http://cscene.org/topics/patterns.xml.html">Patterns</A> <A 
+      href="http://cscene.org/topics/graphics.xml.html">Graphics</A> <A 
+      href="http://cscene.org/topics/misc.xml.html">Miscellaneous</A> <A 
+      href="http://cscene.org/topics/unix.xml.html">UNIX</A> <A 
+      href="http://cscene.org/topics/web.xml.html">Web &amp; XML</A> <A 
+      href="http://cscene.org/topics/windows.xml.html">Windows</A> <BR><A 
+      href="http://cscene.org/feedback.html">Feedback</A> <A 
+      href="http://cscene.org/faqs.html">FAQs</A> <A 
+      href="http://cscene.org/changes.html">Changes</A> <A 
+      href="http://cscene.org/submit.html">Submissions</A> </TD>
+    <TD>
+      <FORM action=http://www.google.com/search method=get><INPUT name=hl 
+      type=hidden value=en><INPUT name=safe type=hidden value=off><INPUT 
+      name=domains type=hidden value=cscene.org><INPUT name=sitesearch 
+      type=hidden value=cscene.org><INPUT maxLength=256 name=q size=31><INPUT name=btnG type=submit value=Search></FORM></TD></TR></TBODY></TABLE>
+<H1 class=s1>Callbacks in C++: The OO Way</H1>
+<DIV class=toc>
+<H2 class=s2 id=N1698364>Content</H2>
+<OL>
+  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N7895983">What are 
+  Callbacks?</A>
+  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N310499">A simple 
+  Thread class</A>
+  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N7751758">Thread 
+  implementation</A>
+  <LI><A href="http://cscene.org/topics/misc/cs7-04.xml.html#N3038356">A real 
+  Thread class</A></LI></OL></DIV>
+<DIV class=article>
+<P>by <I>Jürgen Hermann</I><BR>last updated <I>2001/08/02</I> (version 
+<I>1.1.1.1</I>)<BR>also available as <A 
+href="http://cscene.org/topics/misc/cs7-04.xml.txt">XML</A></P>
+<DIV class=s2>
+<H2 class=s2 id=N7895983>What are Callbacks?</H2>
+<P>Many operating systems and other subsystems (like GUI libraries) feature a 
+special type of hook into those systems, named callbacks or callback functions. 
+Upon initialization or by calling an API function you pass pointers to the 
+callback into the subsystem, for later use. The problem with those functions is, 
+since these subsystems are nowadays not yet OO, that they have no notion of what 
+an object is. So if you want to have a <EM>callback object&nbsp;</EM> instead of 
+a mere function, some OO magic is called for.</P>
+<P>As an example, consider the <CODE>BeginThread</CODE> API that many OSes have 
+in a quite similar form; we assume that it takes a pointer to the function that 
+provides the actual code for the newly created thread plus a <EM>data 
+pointer&nbsp;</EM> that is passed to that function as a startup parameter. Thus, 
+we end up with <CODE>BeginThread (void (*thread_func) (void*), void* 
+startup_data)</CODE>. Now let's make a <CODE>Thread</CODE> class of 
+that.</P></DIV>
+<DIV class=s2>
+<H2 class=s2 id=N310499>A simple Thread class</H2>
+<P>What we want to have is an ABC (abstract base class) that you can inherit 
+from, creating specialized thread classes and in turn thread objects (i.e. 
+actual threads). The code of the thread is located in a <EM>pure 
+virtual&nbsp;</EM> function <CODE>code</CODE> that is provided by the inherited 
+class. <CODE>code</CODE> is then similar to the <CODE>thread_func</CODE> 
+parameter of the <CODE>BeginThread</CODE> call, but is a full-blown member 
+function, not just a C function. So, we get this interface for the 
+<CODE>Thread</CODE> class:</P><PRE class=source>class Thread {
+public:
+    virtual ~Thread();
+    void run();
+
+protected:
+    Thread();
+    virtual void code() = 0;
+
+private:
+    int running;
+
+    static void dispatch(void* thread_obj);
+};
+</PRE>
+<P>This might seem quite unusual to you (like having a protected constructor), 
+but things will be explained in due course.</P></DIV>
+<DIV class=s2>
+<H2 class=s2 id=N7751758>Thread implementation</H2>
+<P>When we put the thread concept into a class, we have to consider lifetime. A 
+thread exists as long as the thread function does not return, thus the object 
+has to have the same lifetime. Because of this, an <CODE>auto</CODE> thread 
+object does not make much sense; we insure that every thread object exists on 
+the heap by making the ctor protected and providing a static factory method 
+<CODE>create</CODE> for thread objects in each derived class:</P><PRE class=source>Thread::Thread() 
+    : running(0) 
+{
+}
+
+DerivedThread&amp; DerivedThread::create()
+{
+    return *new DerivedThread;
+}
+</PRE>
+<P><CODE>create</CODE> has to be added to every inherited class, returning an 
+object of that class.</P>
+<P>Next, we need a <CODE>run</CODE> method that actually starts the thread. This 
+can't be done in the ctor: when <CODE>code</CODE> would be registered as a 
+thread of execution in the <EM>base class&nbsp;</EM> ctor, the superclass would 
+not yet be fully created and calling <CODE>code</CODE> would be quite invalid 
+and dangerous. <CODE>run</CODE> does its job by registering the 
+<CODE>dispatch</CODE> function as a thread, giving that thread the object 
+pointer as a startup parameter; since <CODE>dispatch</CODE> is static, it has a 
+prototype that matches the <CODE>void(*)(void*)</CODE> parameter of 
+<CODE>BeginThread</CODE>.</P><PRE class=source>void Thread::run()
+{
+    // Don't start two threads on the same object
+    if (running) return;
+
+    // Create an OS thread, using the static callback
+    BeginThread(Thread::dispatch, this);
+    running = 1;
+}
+</PRE>
+<P>So finally, <CODE>dispatch</CODE> is called and performs the step from a 
+procedural callback to the callback object:</P><PRE class=source>void Thread::dispatch(void* thread_obj)
+{
+    // Call the actual OO thread code
+    ((Thread*)thread_obj)-&gt;code();
+
+    // After code() returns, kill the thread object
+    delete (Thread*)thread_obj;
+}
+</PRE></DIV>
+<DIV class=s2>
+<H2 class=s2 id=N3038356>A real Thread class</H2>
+<P>A real-world thread class has to consider a few things we have ignored here. 
+These things include: </P>
+<OL class=userlist>
+  <LI>more access to the thread data, like a method giving the thread ID. 
+  <LI>a method for killing the thread, including the deletion of the thread 
+  object. </LI></OL>
+<P>Developed and tested on Windows NT, this is the <A 
+href="../../tests/oo_thread.cpp">source</A> for a little 
+example program that implements the above in the real world. If you run it, you 
+get something similar to the following output:</P><PRE class=source>[\cscene\callback]callback
+Started thread #80 for dice1
+Started thread #84 for dice2
+dice1 rolled 1
+dice2 rolled 1
+dice2 rolled 3
+dice1 rolled 1
+dice2 rolled 4
+dice1 rolled 6
+dice1 rolled 3
+dice2 rolled 3
+dice1 rolled 1
+dice1 rolled 4
+dice2 rolled 4
+dice2 rolled 3
+dice1 rolled 1
+dice2 rolled 6
+dice1 rolled 2
+dice2 rolled 2
+dice1 rolled 1
+dice2 rolled 4
+dice2 rolled 1
+dice1 rolled 4
+dice1 rolled 5
+dice2 rolled 1
+dice1 rolled 3
+dice2 rolled 3
+dice1 rolled 2
+dice1 rolled 6
+dice2 rolled 2
+dice1 rolled 1
+dice2 rolled 3
+dice1 rolled 4
+dice1 rolled 5
+dice2 rolled 3
+dice2 rolled 6
+dice1 rolled 4
+</PRE>
+<P>Have fun!</P></DIV>
+<P><SMALL><EM>This article is Copyright © 1997-98 by Jürgen Hermann<BR>and 
+Copyright © 1999 by C-Scene. All Rights Reserved. </EM></SMALL></P></DIV>
+<DIV class=lastwords>
+<HR>
+Copyright © 1997-2000 by C-Scene. All Rights Reserved.<BR><BR>Part of the 
+graphics and stylesheets used to generate this site are<BR>Copyright © 1999-2000 
+by Apache Software Foundation. </DIV></BODY></HTML>