2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-21 05:02:17 +00:00
Files
python/doc/v2/class.html
Dave Abrahams 8f1dc2522a Added Dereferenceable
[SVN r13808]
2002-05-10 15:46:37 +00:00

552 lines
18 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<meta name="generator" content="HTML Tidy, see www.w3.org">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" type="text/css" href="../boost.css">
<title>Boost.Python - &lt;boost/python/class.hpp&gt;,
&lt;boost/python/class_fwd.hpp&gt;</title>
<table border="0" cellpadding="7" cellspacing="0" width="100%" summary=
"header">
<tr>
<td valign="top" width="300">
<h3><a href="../../../../index.htm"><img height="86" width="277" alt=
"C++ Boost" src="../../../../c++boost.gif" border="0"></a></h3>
<td valign="top">
<h1 align="center">Boost.Python</h1>
<h2 align="center">Headers &lt;boost/python/class.hpp&gt;,
&lt;boost/python/class_fwd.hpp&gt;</h2>
</table>
<hr>
<h2>Contents</h2>
<dl class="page-index">
<dt><a href="#introduction">Introduction</a>
<dt><a href="#classes">Classes</a>
<dd>
<dl class="page-index">
<dt><a href="#class_-spec">Class template <code>class_</code></a>
<dd>
<dl class="page-index">
<dt><a href="#class_-spec-synopsis">Class <code>class_</code>
synopsis</a>
<dt><a href="#class_-spec-ctors">Class <code>class_</code>
constructors</a>
<dt><a href="#class_-spec-modifiers">Class <code>class_</code>
modifier functions</a>
<dt><a href="#class_-spec-observers">Class <code>class_</code>
observer functions</a>
</dl>
<dt><a href="#bases-spec">Class template <code>bases</code></a>
<dd>
<dl class="page-index">
<dt><a href="#bases-spec-synopsis">Class <code>bases</code>
synopsis</a>
</dl>
<dt><a href="#args-spec">Class template <code>args</code></a>
<dd>
<dl class="page-index">
<dt><a href="#args-spec-synopsis">Class <code>args</code>
synopsis</a>
</dl>
</dl>
<dt><a href="#examples">Example(s)</a>
</dl>
<hr>
<h2><a name="introduction"></a>Introduction</h2>
<p><code>&lt;boost/python/class.hpp&gt;</code> defines the interface
through which users expose their C++ classes to Python. It declares the
<code>class_</code> class template, which is parameterized on the
class type being exposed. It also exposes the <code>args</code>
and <code>bases</code> utility class templates, which are used in
conjunction with <code>class_</code>.
<p><code>&lt;boost/python/class_fwd.hpp&gt;</code> contains a forward
declaration of the <code>class_</code> class template.
<h2><a name="classes"></a>Classes</h2>
<h3><a name="class_-spec"></a>Class template <code>class_&lt;T, Bases, <a
href="HolderGenerator.html">HolderGenerator</a>&gt;</code></h3>
<p>Creates a Python class associated with the C++ type passed as
its first parameter. Although it has four template parameters,
only the first one is required. The three optional arguments can
actually be supplied <font color="#007f00"><b>in any
order</b></font>; Boost.Python determines the role of the argument
from its type.<br>
<br>
<table border="1" summary="class_ template parameters">
<tr>
<th>Template Parameter
<th>Requirements
<th>Semantics
<th>Default
<tr>
<td><code>T</code>
<td>A class type.
<td>The class being wrapped
<tr>
<td><code><font color="#007f00">Bases</font></code>
<td>A specialization of <a
href="#bases-spec"><code>bases&lt;...&gt;</code></a> which
specifies previously-exposed C++ base classes of <code>T</code><a href="#footnote_1">[1]</a>.
<td>Registers <code>from_python</code> conversions from
wrapped <code>T</code> instances to each of its exposed direct
and indirect bases. For each polymorphic base <code>B</code>,
registers conversions from indirectly-held wrapped
<code>B</code> instances to <code>T</code>.
<td><code><a href="#bases">bases&lt;&gt;</a></code>
<tr>
<td><code><font color="#007f00">HeldType</font></code>
<td>Must be <code>T</code>, a class derived
from <code>T</code>, or a <a
href="Dereferenceable.html">Dereferenceable</a> type for which
<code><a
href="pointee.html#pointee-spec">pointee</a>&lt;HeldType&gt;::type</code>
is <code>T</code> or a class derived from <code>T</code>.
</dl>
<td>Specifies the type which is actually embedded in a Python
object wrapping a <code>T</code> instance. More details <a
href="#HeldType">below</a>.
<td><code>T</code>
<tr>
<td><code><font color="#007f00">NonCopyable</font></code>
<td>If supplied, must be <a
href="../../../utility/utility.htm#Class noncopyable">boost::noncopyable</a>.
<td> Suppresses automatic registration of <code>to_python</code>
conversions which copy
<code>T</code> instances. Required when <code>T</code> has no
publicly-accessible copy constructor.
<td>An unspecified type other than <code>boost::noncopyable</code>.
</table>
<h4><a name="#HeldType">HeldType Semantics</a></h4>
<ol>
<li>
If <code>HeldType</code> is derived from T, its
exposed constructor(s) must accept an initial
<code>PyObject*</code> argument which refers back to the Python
object that contains it, as shown in <a
href="call_method.html#example">this example</a>. This argument is
not included in the argument list type passed to <a
href="#def_init-spec"><code>def_init()</code></a>, below, nor is
it passed explicitly by users when Python instances of
<code>T</code> are created. This is the idiom which allows C++ virtual
functions to be overridden in Python. Boost.Python automatically
registers additional converters which allow wrapped instances of
<code>T</code> to be passed to wrapped C++ functions expecting
<code>HeldType</code> arguments.
<li>Because Boost.Python will always allow
wrapped instances of <code>T</code> to be passed in place of
<code>HeldType</code> arguments, specifying a smart pointer for
<code>HeldType</code> allows users to pass Python
<code>T</code> instances where a smart pointer-to-<code>T</code> is
expected. Smart pointers such as <code>std::auto_ptr&lt;&gt;</code>
or <code><a
href="../../../smart_ptr/shared_ptr.html">boost::shared_ptr&lt;&gt;</a></code>
which contain a nested type <code>element_type</code> designating
the referent type are automatically supported; additional smart
pointer types can be supported by specializing <a
href="pointee.html#pointee-spec">pointee&lt;HeldType&gt;</a>.
<li>
As in case 1 above, when <code>HeldType</code> is a smart pointer to
a class derived from <code>T</code>, the initial
<code>PyObject*</code> argument must be supplied by all exposed
constructors.
<li>
Except in cases 1 and 3, users may optionally specify that T itself
gets initialized with a similar initial <code>PyObject*</code>
argument by specializing <a
href="has_back_reference.html#has_back_reference-spec">has_back_reference<T></a>.
</ol>
<h4><a name="class_-spec-synopsis"></a>Class template
<code>class_</code> synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;class T
<font color="#007f00"> , class Bases = bases&lt;&gt;
, class HeldType = T
, class NonCopyable = <i>unspecified</i>
&gt;
</font> class class_
{
class_();
class_(char const* name);
// exposing constructors
class_&amp; def_init();
template &lt;class Args&gt;
class_&amp; def_init(Args const&amp; = Args());
template &lt;class Args, class CallPolicy&gt;
self&amp; def_init(Args const&amp;, CallPolicy policy);
// exposing member functions
template &lt;class F&gt;
class_&amp; def(char const* name, F f);
template &lt;class Fn, class CallPolies&gt;
class_&amp; def(char const* name, Fn fn, CallPolies);
// exposing data members
template &lt;class D&gt;
self&amp; def_readonly(char const* name, D T::*pm);
template &lt;class D&gt;
self&amp; def_readwrite(char const* name, D T::*pm);
// property creation
void add_property(char const* name, ref const&amp; fget);
void add_property(char const* name, ref const&amp; fget, ref const&amp; fset);
// accessing the Python class object
ref object() const;
};
}}
</pre>
<h4><a name="class_-spec-ctors"></a>Class template <code>class_</code> constructors</h4>
<pre>
class_();
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> The platform's <code>std::type_info::name()</code>
implementation produces a string which corresponds to the type's
declaration in C++
<dt><b>Effects:</b> Constructs a <code>class_</code> object which
generates a Boost.Python extension class with the same name as
<code>T</code>.
<dt><b>Rationale:</b> Many platforms can generate reasonable names for
Python classes without user intervention.
</dl>
<pre>
class_(char const* name);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>.
<dt><b>Effects:</b> Constructs a <code>class_</code> object which
generates a Boost.Python extension class named <code>name</code>.
<dt><b>Rationale:</b> Gives the user full control over class naming.
</dl>
<h4><a name="class_-spec-modifiers"></a>Class template <code>class_</code>
modifier functions</h4>
<pre>
class_&amp; def_init();
template &lt;class Args&gt;
class_&amp; def_init(Args const&amp; argument_types);
template &lt;class Args, class CallPolicies&gt;
class_&amp; def_init(Args const&amp; argument_types, CallPolicies policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>Args</code> is an <a
href="../../../mpl/doc/Sequences.html">MPL sequence</a> of C++ argument
types (<i>A1, A2,... AN</i>) such that if
<code>a1, a2</code>... <code>aN</code> are objects of type
<i>A1, A2,... AN</i> respectively, the expression
<code>T(a1, a2</code>... <code>aN</code>) is valid. In the first form,
the expression <code>T()</code> must be valid.
<dt><b>Effects:</b> Adds the result of
<code><a href=
"make_function.html#make_constructor-spec">make_constructor</a>&lt;args&lt;&gt;,Holder&gt;()</code>,
<code><a href=
"make_function.html#make_constructor-spec">make_constructor</a>&lt;Args,Holder&gt;()</code>, or
<code><a href=
"make_function.html#make_constructor-spec">make_constructor</a>&lt;Args,Holder&gt;(policies)</code>,
respectively, to the Boost.Python extension class being defined under the name
"__init__". <code>Holder</code> is a model of <a
href="Holder.html">Holder</a> which contains the
<code>HeldType</code>. If the extension class
already has an "__init__" attribute, the usual <a
href="http:overloading.html">overloading procedure</a> applies.
<dt><b>Returns:</b> <code>*this</code>
<dt><b>Rationale:</b> Allows users to easily expose a class' constructor
to Python.
</dl>
<br>
<pre>
template &lt;class F&gt;
class_&amp; def(char const* name, F f);
template &lt;class Fn, class CallPolicies&gt;
class_&amp; def(char const* name, Fn f, CallPolicies policies);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>f</code> is a non-null pointer-to-function or
pointer-to-member-function. <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>. In the first form, the return type of
<code>f</code> is not a reference and is not a pointer other
than <code>char const*</code> or <code>PyObject*</code>. In the
second form <code>policies</code> is a model of <a
href="CallPolicies.html">CallPolicies</a>.
<dt><b>Effects:</b> Adds the result of <code><a href=
"make_function.html#make_function-spec">make_function</a>(f)</code> to
the Boost.Python extension class being defined, with the given
<code>name</code>. If the extension class already has an attribute named
<code><i>name</i></code>, the usual <a href=
"overloading.html">overloading procedure</a> applies.
<dt><b>Returns:</b> <code>*this</code>
</dl>
<br>
<pre>
void add_property(char const* name, ref const&amp;amp; fget);
void add_property(char const* name, ref const&amp;amp; fget, ref const&amp;amp; fset);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>.
<dt><b>Effects:</b> Creates a new Python <a
href="http://www.python.org/2.2/descrintro.html#property"><code>property</code></a>
class instance, passing <code>fget.get()</code> (and
<code>fset.get()</code> in the second form) to its constructor,
then adds that property to the Python class object under
construction with the given attribute <code>name</code>.
<dt><b>Returns:</b> <code>*this</code>
<dt><b>Rationale:</b> Allows users to easily expose a class'
data member such that it can be inspected from Python with a
natural syntax.
</dl>
<br>
<pre>
template &lt;class D&gt;
self&amp; def_readonly(char const* name, D T::*pm);
</pre>
<dl class="function-semantics">
<dt><b>Requires:</b> <code>name</code> is a ntbs which conforms to
Python's <a href=
"http://www.python.org/doc/2.2/ref/identifiers.html">identifier
naming rules</a>.
<dt><b>Effects:</b>
<pre>
this-&gt;add_property(name, ref(<a href="data_members.html#make_getter-spec">make_getter</a>(pm)));
</pre>
<dt><b>Returns:</b> <code>*this</code>
<dt><b>Rationale:</b> Allows users to easily expose a class'
data member such that it can be inspected from Python with a
natural syntax.
</dl>
<br>
<pre>
template &lt;class D&gt;
self&amp; def_readwrite(char const* name, D T::*pm);
</pre>
<dl class="function-semantics">
<dt><b>Effects:</b>
<pre>
ref fget(<a href="data_members.html#make_getter-spec">make_getter</a>(pm));
ref fset(<a href="data_members.html#make_setter-spec">make_setter</a>(pm));
this-&gt;add_property(name, fget, fset);
</pre>
<dt><b>Returns:</b> <code>*this</code>
<dt><b>Rationale:</b> Allows users to easily expose a class'
data member such that it can be inspected and set from Python with a
natural syntax.
<h4><a name="class_-spec-observers"></a>Class template <code>class_</code>
observer functions</h4>
<pre>
ref object() const;
</pre>
<dl class="function-semantics">
<dt><b>Returns:</b> A <code>ref</code> object which holds a reference to
the Boost.Python extension class object created by the
<code>class_</code> constructor.
<dt><b>Rationale:</b> Mostly not needed by users, since <code><a href=
"module.html#add-spec">module::add</a>()</code> uses this to insert the
extension class in the module.
</dl>
<h3><a name="args-spec"></a>Class template
<code>args&lt;T1, T2,</code>...<code>TN&gt;</code></h3>
<p>A conveniently-named <a
href="../../../mpl/doc/Sequences.html">MPL sequence</a> which
users pass to <code><a
href="#class_-spec-modifiers">def_init</a></code> calls to make
their code more readable.
<h4><a name="args-spec-synopsis"></a>Class template <code>args</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;T1 = <i>unspecified</i>,...TN = <i>unspecified</i>&gt;
struct args
{};
}}
</pre>
<h3><a name="bases-spec"></a>Class template
<code>bases&lt;T1, T2,</code>...<code>TN&gt;</code></h3>
<p>An <a
href="../../../mpl/doc/Sequences.html">MPL sequence</a> which
can be used in <code>class_&lt;</code>...<code>&gt;</code>
instantiations indicate a list of base classes. Although users
can pass any MPL sequence in place of args, above, the use of
<code>bases</code> to indicate base classes is mandatory.
<h4><a name="bases-spec-synopsis"></a>Class template <code>bases</code>
synopsis</h4>
<pre>
namespace boost { namespace python
{
template &lt;T1 = <i>unspecified</i>,...TN = <i>unspecified</i>&gt;
struct bases
{};
}}
</pre>
<h2><a name="examples"></a>Example(s)</h2>
<p>Given a C++ class declaration:
<pre>
class Foo : public Bar, public Baz
{
public:
Foo(int, char const*);
Foo(double);
std::string const&amp; name() { return m_name; }
void name(char const*);
double value; // public data
private:
...
};
</pre>
A corresponding Boost.Python extension class can be created with:
<pre>
using namespace boost::python;
ref foo = class_&lt;Foo,bases&lt;Bar,Baz&gt; &gt;()
.def_init(args&lt;int,char const*&gt;())
.def_init(args&lt;double&gt;())
.def("get_name", &amp;Foo::get_name, return_internal_reference&lt;&gt;())
.def("set_name", &amp;Foo::set_name)
.def_readwrite("value", &amp;Foo::value)
.object();
</pre>
<hr>
<a name="footnote_1">[1]</a> By &quot;previously-exposed&quot; we mean that the for each
<code>B</code> in <code>bases</code>, an instance of
<code>class_&lt;B&gt;</code> must have already been
constructed. Ensuring this in a portable manner when a class and its
bases are exposed in the same module entails using separate
<i>full-expressions</i>, rather than chaining consecutive definitions with
&quot;<code>.add(...)</code>.
<pre>
module m(&quot;module_name&quot;);
m.add(class_&lt;Base&gt;()
.def_init());
m.add(class_&lt;Derived, bases&lt;Base&gt;&gt;()
.def_init());
</pre>
Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->
09 May, 2002 <!-- Luann's birthday! -->
<!--webbot bot="Timestamp" endspan i-checksum="39359" -->
<p><i>&copy; Copyright <a href="../../../../people/dave_abrahams.htm">Dave
Abrahams</a> 2002. All Rights Reserved.</i>