|
| 1 | +<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
| 2 | + |
| 3 | + <meta name="generator" content="HTML Tidy, see www.w3.org"> |
| 4 | + <meta http-equiv="Content-Type" content= |
| 5 | + "text/html; charset=iso-8859-1"> |
| 6 | + <link rel="stylesheet" type="text/css" href="../boost.css"> |
| 7 | + |
| 8 | + <title>Boost.Python - <boost/python/instance_holder.hpp></title> |
| 9 | +<style type="text/css"> |
| 10 | + p.c4 {font-style: italic} |
| 11 | + span.c3 {color: #ff0000} |
| 12 | + h2.c2 {text-align: center} |
| 13 | + h1.c1 {text-align: center} |
| 14 | +</style> |
| 15 | + |
| 16 | + <table border="0" cellpadding="7" cellspacing="0" width="100%" |
| 17 | + summary="header"> |
| 18 | + <tr> |
| 19 | + <td valign="top" width="300"> |
| 20 | + <h3><a href="../../../../index.htm"><img height="86" width= |
| 21 | + "277" alt="C++ Boost" src="../../../../c++boost.gif" border= |
| 22 | + "0"></a></h3> |
| 23 | + |
| 24 | + <td valign="top"> |
| 25 | + <h1 class="c1">Boost.Python</h1> |
| 26 | + |
| 27 | + <h2 class="c2">Header <boost/python/instance_holder.hpp></h2> |
| 28 | + </table> |
| 29 | + <hr> |
| 30 | + |
| 31 | + <h2>Contents</h2> |
| 32 | + |
| 33 | + <dl class="page-index"> |
| 34 | + <dt><a href="#introduction">Introduction</a> |
| 35 | + |
| 36 | + <dt><a href="#classes">Classes</a> |
| 37 | + |
| 38 | + <dd> |
| 39 | + <dl class="page-index"> |
| 40 | + <dt><a href="#instance_holder-spec">Class |
| 41 | + <code>instance_holder</code></a> |
| 42 | + |
| 43 | + <dd> |
| 44 | + <dl class="page-index"> |
| 45 | + <dt><a href="#instance_holder-spec-synopsis">Class |
| 46 | + <code>instance_holder</code> synopsis</a> |
| 47 | + |
| 48 | + <dt><a href="#instance_holderspec-ctors">Class |
| 49 | + <code>instance_holder</code> destructor</a> |
| 50 | + |
| 51 | + <dt><a href="#instance_holderspec-modifiers">Class |
| 52 | + <code>instance_holder</code> modifier functions</a> |
| 53 | + |
| 54 | + <dt><a href="#instance_holderspec-observers">Class |
| 55 | + <code>instance_holder</code> observer functions</a> |
| 56 | + </dl> |
| 57 | + </dl> |
| 58 | + |
| 59 | + <dt><a href="#examples">Example</a> |
| 60 | + </dl> |
| 61 | + <hr> |
| 62 | + |
| 63 | + <h2><a name="introduction"></a>Introduction</h2> |
| 64 | + |
| 65 | + <p><code><boost/python/instance_holder.hpp></code> provides |
| 66 | + <code>class instance_holder</code>, the base class for types |
| 67 | + which hold C++ instances of wrapped classes. |
| 68 | + |
| 69 | + <h2><a name="classes"></a>Classes</h2> |
| 70 | + |
| 71 | + <h3><a name="instance_holder-spec"></a>Class <code>instance_holder</code></h3> |
| 72 | + |
| 73 | + <p><code>instance_holder</code> is an abstract base class whose |
| 74 | + concrete derived classes hold C++ class instances within their |
| 75 | + Python object wrappers. To allow multiple inheritance in Python |
| 76 | + from C++ class wrappers, each such Python object contains a chain |
| 77 | + of <code>instance_holder</code>s. When an <code>__init__</code> |
| 78 | + function for a wrapped C++ class is invoked, a new |
| 79 | + <code>instance_holder</code> instance is created and installed in |
| 80 | + the Python object using its <code><a |
| 81 | + href="#instance_holder-spec-modifiers">install</a></code>() |
| 82 | + function. Each concrete class derived from |
| 83 | + <code>instance_holder</code> must provide a <code><a |
| 84 | + href="#instance_holder-spec-observers">holds</a>()</code> |
| 85 | + implementation which allows Boost.Python to query it for the |
| 86 | + type(s) it is holding. In order to support the held type's wrapped |
| 87 | + constructor(s), the class must also provide constructors that can |
| 88 | + accept an initial <code>PyObject*</code> argument referring to the |
| 89 | + owning Python object, and which forward the rest of their |
| 90 | + arguments to the constructor of the held type. The initial |
| 91 | + argument is needed to enable virtual function overriding in |
| 92 | + Python, and may be ignored, depending on the specific |
| 93 | + <code>instance_holder</code> subclass. |
| 94 | + |
| 95 | + <h4><a name="instance_holder-spec-synopsis"></a>Class instance_holder |
| 96 | + synopsis</h4> |
| 97 | +<pre> |
| 98 | +namespace boost { namespace python |
| 99 | +{ |
| 100 | + class instance_holder : <a href="../../../utility/utility.htm#Class noncopyable">noncopyable</a> |
| 101 | + { |
| 102 | + public: |
| 103 | + // destructor |
| 104 | + virtual ~instance_holder(); |
| 105 | + |
| 106 | + // instance_holder modifiers |
| 107 | + void install(PyObject* inst) throw(); |
| 108 | + |
| 109 | + // instance_holder observers |
| 110 | + virtual void* holds(type_info) = 0; |
| 111 | + }; |
| 112 | +}} |
| 113 | +</pre> |
| 114 | + |
| 115 | + <h4><a name="instance_holderspec-ctors">Class <code>instance_holder</code> |
| 116 | + destructor</a></h4> |
| 117 | +<pre> |
| 118 | +virtual ~instance_holder(); |
| 119 | +</pre> |
| 120 | + |
| 121 | + <dl class="function-semantics"> |
| 122 | + <dt><b>Effects:</b> destroys the object |
| 123 | + </dl> |
| 124 | + |
| 125 | + <h4><a name="instance_holderspec-modifiers">Class |
| 126 | + <code>instance_holder</code> modifiers</a></h4> |
| 127 | +<pre> |
| 128 | +void install(PyObject* inst) throw(); |
| 129 | +</pre> |
| 130 | + |
| 131 | + <dl class="function-semantics"> |
| 132 | + <dt><b>Requires:</b> <code>inst</code> is a Python instance of a |
| 133 | + wrapped C++ class type, or is a type derived from a wrapped C++ |
| 134 | + class type. |
| 135 | + <dt><b>Effects:</b> installs the new instance at the head of the |
| 136 | + Python object's chain of held instances. |
| 137 | + <dt><b>Throws:</b> nothing |
| 138 | + </dl> |
| 139 | + |
| 140 | + <h4><a name="instance_holderspec-observers">Class <code>instance_holder</code> |
| 141 | + observers</a></h4> |
| 142 | +<pre> |
| 143 | +virtual void* holds(type_info x) = 0; |
| 144 | +</pre> |
| 145 | + |
| 146 | + <dl class="function-semantics"> |
| 147 | + <dt><b>Returns:</b> A pointer to an object of the type described |
| 148 | + by <code>x</code> if <code>*this</code> contains such an object, |
| 149 | + 0 otherwise. |
| 150 | + </dl> |
| 151 | + |
| 152 | + <h2><a name="examples"></a>Example</h2> |
| 153 | + |
| 154 | +The following is a simplified version of the instance holder template |
| 155 | +used by Boost.Python to wrap classes held by smart pointers: |
| 156 | +<pre> |
| 157 | +template <class SmartPtr, class Value> |
| 158 | +struct pointer_holder : instance_holder |
| 159 | +{ |
| 160 | + // construct from the SmartPtr type |
| 161 | + pointer_holder(SmartPtr p) |
| 162 | + :m_p(p) |
| 163 | + |
| 164 | + // Forwarding constructors for the held type |
| 165 | + pointer_holder(PyObject*) |
| 166 | + :m_p(new Value()) |
| 167 | + { |
| 168 | + } |
| 169 | + |
| 170 | + template<class A0> |
| 171 | + pointer_holder(PyObject*,A0 a0) |
| 172 | + :m_p(new Value(a0)) |
| 173 | + { |
| 174 | + } |
| 175 | + |
| 176 | + template<class A0,class A1> |
| 177 | + pointer_holder(PyObject*,A0 a0,A1 a1) |
| 178 | + :m_p(new Value(a0,a1)) |
| 179 | + { |
| 180 | + } |
| 181 | + ... |
| 182 | + |
| 183 | + private: // required holder implementation |
| 184 | + void* holds(type_info dst_t) |
| 185 | + { |
| 186 | + // holds an instance of the SmartPtr type... |
| 187 | + if (dst_t == python::type_id<SmartPtr>()) |
| 188 | + return &this->m_p; |
| 189 | + |
| 190 | + // ...and an instance of the SmartPtr's element_type, if the |
| 191 | + // pointer is non-null |
| 192 | + return python::type_id<Value>() == dst_t ? &*this->m_p : 0; |
| 193 | + } |
| 194 | + |
| 195 | + private: // data members |
| 196 | + SmartPtr m_p; |
| 197 | +}; |
| 198 | +</pre> |
| 199 | + |
| 200 | + <p>Revised |
| 201 | + <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan --> |
| 202 | + 19 November, 2002 |
| 203 | + <!--webbot bot="Timestamp" endspan i-checksum="39359" --> |
| 204 | + |
| 205 | + |
| 206 | + <p class="c4">© Copyright <a href= |
| 207 | + "../../../../people/dave_abrahams.htm">Dave Abrahams</a> 2002. All |
| 208 | + Rights Reserved. |
| 209 | + |
0 commit comments