2
0
mirror of https://github.com/boostorg/python.git synced 2026-01-22 05:22:45 +00:00

initial checkin

[SVN r8087]
This commit is contained in:
Dave Abrahams
2000-10-31 22:21:10 +00:00
parent de34ef3e9d
commit b2d0dbd291

164
inheritance.html Normal file
View File

@@ -0,0 +1,164 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"
"http://www.w3.org/TR/REC-html40/strict.dtd">
<title>
Inheritance
</title>
<div>
<h1>
<img width="277" height="86" id="_x0000_i1025" align="center"
src="c++boost.gif" alt= "c++boost.gif (8819 bytes)">Inheritance
</h1>
<h2>Inheritance in Python</h2>
<p>
Py_cpp extension classes support single and multiple-inheritance in
Python, just like regular Python classes. You can mix built-in Python
classes with py_cpp extension classes in a derived class' tuple of
bases. Whenever a py_cpp extension class is among the bases for a new
class in Python, the result is an extension class:
<blockquote>
<pre>
&gt;&gt;&gt; class MyPythonClass:
... def f(): return 'MyPythonClass.f()'
...
&gt;&gt;&gt; import my_extension_module
&gt;&gt;&gt; class Derived(my_extension_module.MyExtensionClass, MyPythonClass):
... '''This is an extension class'''
... pass
...
&gt;&gt;&gt; x = Derived()
&gt;&gt;&gt; x.f()
'MyPythonClass.f()'
&gt;&gt;&gt; x.g()
'MyExtensionClass.g()'
</pre>
</blockquote>
<h2>Reflecting C++ Inheritance Relationships</h2>
<p>
Py_cpp also allows us to represent C++ inheritance relationships so that
wrapped derived classes may be passed where values, pointers, or
references to a base class are expected as arguments:
<blockquote>
<pre>
#include <memory> // for std::auto_ptr<>
struct Base
{
virtual ~Base() {}
virtual const char* name() const { return "Base"; }
};
struct Derived
{
Derived() : x(-1) {}
virtual const char* name() const { return "Derived"; }
int x;
};
std::auto_ptr<Base> base_factory() {
return std::auto_ptr<Base>(new Derived);
}
const char* get_name(const Base& b) {
return b.name();
}
int get_derived_x(const Derived& d) {
return d.x;
}
<hr>
#include &lt;py_cpp/class_wrapper.h&gt;
extern "C"
#ifdef _WIN32
__declspec(dllexport)
#endif
void initmy_module()
{
    try
    {
       py::Module my_module("my_module");
       py::ClassWrapper&lt;Base&gt; base_class(my_module, "Base");
       base_class.def(py::Constructor&lt;void&gt;());
       py::ClassWrapper&lt;Derived&gt; derived_class(my_module, "Derived");
       derived_class.def(py::Constructor&lt;void&gt;());
// This establishes the inheritance relationship between Base and Derived
derived_class.declare_base(base_class);
my_module.def(base_factory, "base_factory");
my_module.def(get_name, "get_name");
my_module.def(get_derived_x, "get_derived_x");
    }
    catch(...)
    {
       py::handle_exception();    // Deal with the exception for Python
    }
}
</pre>
</blockquote>
<p>
Then, in Python:
<blockquote>
<pre>
&gt;&gt;&gt; from my_module import *
&gt;&gt;&gt; base = Base()
&gt;&gt;&gt; derived = Derived()
&gt;&gt;&gt; get_name(base)
'Base'
&gt;&gt;&gt; # objects of wrapped class Derived may be passed where Base is expected
&gt;&gt;&gt; get_name(derived)
'Derived'
&gt;&gt;&gt; # objects of wrapped class Derived can be passed where Derived is
&gt;&gt;&gt; # expected but where type information has been lost.
&gt;&gt;&gt; get_derived_x(base_factory())
-1
</pre>
</blockquote>
<h2>Inheritance Without Virtual Functions</h2>
<p>
If for some reason your base class has no virtual functions but you still want
to represent the inheritance relationship between base and derived classes,
pass the special symbol <code>py::without_downcast</code> as the 2nd parameter
to <code>declare_base</code>:
<blockquote>
<pre>
struct Base2 {};
struct Derived2 { int f(); };
<hr>
...
   py::ClassWrapper&lt;Base&gt; base2_class(my_module, "Base2");
   base2_class.def(py::Constructor&lt;void&gt;());
   py::ClassWrapper&lt;Derived2&gt; derived2_class(my_module, "Derived2");
   derived2_class.def(py::Constructor&lt;void&gt;());
derived_class.declare_base(base_class, <b>py::without_downcast</b>);
</pre>
</blockquote>
<p>This approach will allow <code>Derived2</code> objects to be passed where
<code>Base2</code> is expected, but does not attempt to implicitly convert (downcast)
smart-pointers to <code>Base2</code> into <code>Derived2</code> pointers,
references, or values.
<p>
Previous: <a href="overloading.html">Function Overloading</a>
Next: <a href="special.html">Special Method Names</a>
Up: <a href="py_cpp.html">Top</a>
<p>
&copy; Copyright David Abrahams 2000. Permission to copy, use, modify,
sell and distribute this document is granted provided this copyright
notice appears in all copies. This document is provided "as is" without
express or implied warranty, and with no claim as to its suitability
for any purpose.
<p>
Updated: Oct 30, 2000
</div>