⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.10
Server IP:
157.245.101.34
Server:
Linux skvinfotech-website 5.4.0-131-generic #147-Ubuntu SMP Fri Oct 14 17:07:22 UTC 2022 x86_64
Server Software:
Apache/2.4.41 (Ubuntu)
PHP Version:
7.4.33
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
doc
/
libpango1.0-doc
/
gobject
/
View File Name :
howto-gobject-methods.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Object methods: GObject Reference Manual</title> <meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> <link rel="home" href="index.html" title="GObject Reference Manual"> <link rel="up" href="howto-gobject.html" title="How to define and implement a new GObject"> <link rel="prev" href="howto-gobject-destruction.html" title="Object destruction"> <link rel="next" href="howto-gobject-chainup.html" title="Chaining up"> <meta name="generator" content="GTK-Doc V1.32 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle"> <td width="100%" align="left" class="shortcuts"></td> <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td> <td><a accesskey="u" href="howto-gobject.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td> <td><a accesskey="p" href="howto-gobject-destruction.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td> <td><a accesskey="n" href="howto-gobject-chainup.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td> </tr></table> <div class="sect1"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="howto-gobject-methods"></a>Object methods</h2></div></div></div> <p> Just as with C++, there are many different ways to define object methods and extend them: the following list and sections draw on C++ vocabulary. (Readers are expected to know basic C++ concepts. Those who have not had to write C++ code recently can refer to e.g. <a class="ulink" href="http://www.cplusplus.com/doc/tutorial/" target="_top">http://www.cplusplus.com/doc/tutorial/</a> to refresh their memories.) </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"><p> non-virtual public methods, </p></li> <li class="listitem"><p> virtual public methods and </p></li> <li class="listitem"><p> virtual private methods </p></li> </ul></div> <p> </p> <div class="sect2"> <div class="titlepage"><div><div><h3 class="title"> <a name="non-virtual-public-methods"></a>Non-virtual public methods</h3></div></div></div> <p> These are the simplest, providing a simple method which acts on the object. Provide a function prototype in the header and an implementation of that prototype in the source file. </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14</pre></td> <td class="listing_code"><pre class="programlisting"><span class="cm">/* declaration in the header. */</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">);</span> <span class="cm">/* implementation in the source file */</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">VIEWER_IS_FILE</span> <span class="p">(</span><span class="n">self</span><span class="p">));</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="o">*</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span> <span class="cm">/* do stuff here. */</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> </p> </div> <div class="sect2"> <div class="titlepage"><div><div><h3 class="title"> <a name="virtual-public-methods"></a>Virtual public methods</h3></div></div></div> <p> This is the preferred way to create GObjects with overridable methods: </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"><p> Define the common method and its virtual function in the class structure in the public header </p></li> <li class="listitem"><p> Define the common method in the header file and implement it in the source file </p></li> <li class="listitem"><p> Implement a base version of the virtual function in the source file and initialize the virtual function pointer to this implementation in the object’s <code class="function">class_init</code> function; or leave it as <code class="constant">NULL</code> for a ‘pure virtual’ method which must be overridden by derived classes </p></li> <li class="listitem"><p> Re-implement the virtual function in each derived class which needs to override it </p></li> </ul></div> <p> </p> <p> Note that virtual functions can only be defined if the class is derivable, declared using <a class="link" href="gobject-Type-Information.html#G-DECLARE-DERIVABLE-TYPE:CAPS" title="G_DECLARE_DERIVABLE_TYPE()"><code class="function">G_DECLARE_DERIVABLE_TYPE</code></a> so the class structure can be defined. </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35</pre></td> <td class="listing_code"><pre class="programlisting"><span class="cm">/* declaration in viewer-file.h. */</span> <span class="cp">#define VIEWER_TYPE_FILE viewer_file_get_type ()</span> <span class="n">G_DECLARE_DERIVABLE_TYPE</span> <span class="p">(</span><span class="n">ViewerFile</span><span class="p">,</span> <span class="n">viewer_file</span><span class="p">,</span> <span class="n">VIEWER</span><span class="p">,</span> <span class="kt">FILE</span><span class="p">,</span> <span class="n">GObject</span><span class="p">)</span> <span class="k">struct</span> <span class="n">_ViewerFileClass</span> <span class="p">{</span> <span class="n">GObjectClass</span> <span class="n">parent_class</span><span class="p">;</span> <span class="cm">/* stuff */</span> <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">open</span><span class="p">)</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">);</span> <span class="cm">/* Padding to allow adding up to 12 new virtual functions without</span> <span class="cm"> * breaking ABI. */</span> <span class="n">gpointer</span> <span class="n">padding</span><span class="p">[</span><span class="mi">12</span><span class="p">];</span> <span class="p">};</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">);</span> <span class="cm">/* implementation in viewer-file.c */</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span> <span class="n">ViewerFileClass</span> <span class="o">*</span><span class="n">klass</span><span class="p">;</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">VIEWER_IS_FILE</span> <span class="p">(</span><span class="n">self</span><span class="p">));</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="o">*</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span> <span class="n">klass</span> <span class="o">=</span> <span class="n">VIEWER_FILE_GET_CLASS</span> <span class="p">(</span><span class="n">self</span><span class="p">);</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">klass</span><span class="o">-></span><span class="n">open</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">);</span> <span class="n">klass</span><span class="o">-></span><span class="n">open</span> <span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">error</span><span class="p">);</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> The code above simply redirects the <code class="function">open</code> call to the relevant virtual function. </p> <p> It is possible to provide a default implementation for this class method in the object's <code class="function">class_init</code> function: initialize the <code class="function">klass->open</code> field to a pointer to the actual implementation. By default, class methods that are not inherited are initialized to <code class="function">NULL</code>, and thus are to be considered "pure virtual". </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53</pre></td> <td class="listing_code"><pre class="programlisting"><span class="k">static</span> <span class="kt">void</span> <span class="nf">viewer_file_real_close</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* Default implementation for the virtual method. */</span> <span class="p">}</span> <span class="k">static</span> <span class="kt">void</span> <span class="nf">viewer_file_class_init</span> <span class="p">(</span><span class="n">ViewerFileClass</span> <span class="o">*</span><span class="n">klass</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* this is not necessary, except for demonstration purposes.</span> <span class="cm"> *</span> <span class="cm"> * pure virtual method: mandates implementation in children.</span> <span class="cm"> */</span> <span class="n">klass</span><span class="o">-></span><span class="n">open</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">;</span> <span class="cm">/* merely virtual method. */</span> <span class="n">klass</span><span class="o">-></span><span class="n">close</span> <span class="o">=</span> <span class="n">viewer_file_real_close</span><span class="p">;</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span> <span class="n">ViewerFileClass</span> <span class="o">*</span><span class="n">klass</span><span class="p">;</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">VIEWER_IS_FILE</span> <span class="p">(</span><span class="n">self</span><span class="p">));</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="o">*</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span> <span class="n">klass</span> <span class="o">=</span> <span class="n">VIEWER_FILE_GET_CLASS</span> <span class="p">(</span><span class="n">self</span><span class="p">);</span> <span class="cm">/* if the method is purely virtual, then it is a good idea to</span> <span class="cm"> * check that it has been overridden before calling it, and,</span> <span class="cm"> * depending on the intent of the class, either ignore it silently</span> <span class="cm"> * or warn the user.</span> <span class="cm"> */</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">klass</span><span class="o">-></span><span class="n">open</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">);</span> <span class="n">klass</span><span class="o">-></span><span class="n">open</span> <span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">error</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">viewer_file_close</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span> <span class="n">ViewerFileClass</span> <span class="o">*</span><span class="n">klass</span><span class="p">;</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">VIEWER_IS_FILE</span> <span class="p">(</span><span class="n">self</span><span class="p">));</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="o">*</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span> <span class="n">klass</span> <span class="o">=</span> <span class="n">VIEWER_FILE_GET_CLASS</span> <span class="p">(</span><span class="n">self</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">klass</span><span class="o">-></span><span class="n">close</span> <span class="o">!=</span> <span class="nb">NULL</span><span class="p">)</span> <span class="n">klass</span><span class="o">-></span><span class="n">close</span> <span class="p">(</span><span class="n">self</span><span class="p">,</span> <span class="n">error</span><span class="p">);</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> </p> </div> <div class="sect2"> <div class="titlepage"><div><div><h3 class="title"> <a name="virtual-private-methods"></a>Virtual private Methods</h3></div></div></div> <p> These are very similar to <a class="link" href="howto-gobject-methods.html#virtual-public-methods" title="Virtual public methods">virtual public methods</a>. They just don't have a public function to call directly. The header file contains only a declaration of the virtual function: </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19</pre></td> <td class="listing_code"><pre class="programlisting"><span class="cm">/* declaration in viewer-file.h. */</span> <span class="k">struct</span> <span class="n">_ViewerFileClass</span> <span class="p">{</span> <span class="n">GObjectClass</span> <span class="n">parent</span><span class="p">;</span> <span class="cm">/* Public virtual method as before. */</span> <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">open</span><span class="p">)</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">);</span> <span class="cm">/* Private helper function to work out whether the file can be loaded via</span> <span class="cm"> * memory mapped I/O, or whether it has to be read as a stream. */</span> <span class="n">gboolean</span> <span class="p">(</span><span class="o">*</span><span class="n">can_memory_map</span><span class="p">)</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">);</span> <span class="cm">/* Padding to allow adding up to 12 new virtual functions without</span> <span class="cm"> * breaking ABI. */</span> <span class="n">gpointer</span> <span class="n">padding</span><span class="p">[</span><span class="mi">12</span><span class="p">];</span> <span class="p">};</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">);</span></pre></td> </tr> </tbody> </table> </div> <p> These virtual functions are often used to delegate part of the job to child classes: </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27</pre></td> <td class="listing_code"><pre class="programlisting"><span class="cm">/* this accessor function is static: it is not exported outside of this file. */</span> <span class="k">static</span> <span class="n">gboolean</span> <span class="nf">viewer_file_can_memory_map</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">VIEWER_FILE_GET_CLASS</span> <span class="p">(</span><span class="n">self</span><span class="p">)</span><span class="o">-></span><span class="n">can_memory_map</span> <span class="p">(</span><span class="n">self</span><span class="p">);</span> <span class="p">}</span> <span class="kt">void</span> <span class="nf">viewer_file_open</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">,</span> <span class="n">GError</span> <span class="o">**</span><span class="n">error</span><span class="p">)</span> <span class="p">{</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">VIEWER_IS_FILE</span> <span class="p">(</span><span class="n">self</span><span class="p">));</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span> <span class="o">||</span> <span class="o">*</span><span class="n">error</span> <span class="o">==</span> <span class="nb">NULL</span><span class="p">);</span> <span class="cm">/*</span> <span class="cm"> * Try to load the file using memory mapped I/O, if the implementation of the</span> <span class="cm"> * class determines that is possible using its private virtual method.</span> <span class="cm"> */</span> <span class="k">if</span> <span class="p">(</span><span class="n">viewer_file_can_memory_map</span> <span class="p">(</span><span class="n">self</span><span class="p">))</span> <span class="p">{</span> <span class="cm">/* Load the file using memory mapped I/O. */</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="cm">/* Fall back to trying to load the file using streaming I/O… */</span> <span class="p">}</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> </p> <p> Again, it is possible to provide a default implementation for this private virtual function: </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14</pre></td> <td class="listing_code"><pre class="programlisting"><span class="k">static</span> <span class="n">gboolean</span> <span class="nf">viewer_file_real_can_memory_map</span> <span class="p">(</span><span class="n">ViewerFile</span> <span class="o">*</span><span class="n">self</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* As an example, always return false. Or, potentially return true if the</span> <span class="cm"> * file is local. */</span> <span class="k">return</span> <span class="n">FALSE</span><span class="p">;</span> <span class="p">}</span> <span class="k">static</span> <span class="kt">void</span> <span class="nf">viewer_file_class_init</span> <span class="p">(</span><span class="n">ViewerFileClass</span> <span class="o">*</span><span class="n">klass</span><span class="p">)</span> <span class="p">{</span> <span class="cm">/* non-pure virtual method; does not have to be implemented in children. */</span> <span class="n">klass</span><span class="o">-></span><span class="n">can_memory_map</span> <span class="o">=</span> <span class="n">viewer_file_real_can_memory_map</span><span class="p">;</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> </p> <p> Derived classes can then override the method with code such as: </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8</pre></td> <td class="listing_code"><pre class="programlisting"><span class="k">static</span> <span class="kt">void</span> <span class="nf">viewer_audio_file_class_init</span> <span class="p">(</span><span class="n">ViewerAudioFileClass</span> <span class="o">*</span><span class="n">klass</span><span class="p">)</span> <span class="p">{</span> <span class="n">ViewerFileClass</span> <span class="o">*</span><span class="n">file_class</span> <span class="o">=</span> <span class="n">VIEWER_FILE_CLASS</span> <span class="p">(</span><span class="n">klass</span><span class="p">);</span> <span class="cm">/* implement pure virtual function. */</span> <span class="n">file_class</span><span class="o">-></span><span class="n">can_memory_map</span> <span class="o">=</span> <span class="n">viewer_audio_file_can_memory_map</span><span class="p">;</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> </p> </div> </div> <div class="footer"> <hr>Generated by GTK-Doc V1.32</div> </body> </html>