From b2d0dbd291afa7d80c5b6c06b25f3a3e8d6f95b0 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Tue, 31 Oct 2000 22:21:10 +0000 Subject: [PATCH] initial checkin [SVN r8087] --- inheritance.html | 164 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 inheritance.html diff --git a/inheritance.html b/inheritance.html new file mode 100644 index 00000000..138d58a9 --- /dev/null +++ b/inheritance.html @@ -0,0 +1,164 @@ + + + Inheritance + +
+

+ c++boost.gif (8819 bytes)Inheritance +

+ +

Inheritance in Python

+ +

+ 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: +

+
+>>> class MyPythonClass:
+...     def f(): return 'MyPythonClass.f()'
+...
+>>> import my_extension_module
+>>> class Derived(my_extension_module.MyExtensionClass, MyPythonClass):
+...     '''This is an extension class'''
+...     pass
+...
+>>> x = Derived()
+>>> x.f()
+'MyPythonClass.f()'
+>>> x.g()
+'MyExtensionClass.g()'
+
+
+ +

Reflecting C++ Inheritance Relationships

+

+ 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: + +

+
+#include  // 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_factory() {
+    return std::auto_ptr(new Derived);
+}
+
+const char* get_name(const Base& b) {
+    return b.name();
+}
+
+int get_derived_x(const Derived& d) {
+    return d.x;
+}
+    
+#include <py_cpp/class_wrapper.h> +extern "C" +#ifdef _WIN32 +__declspec(dllexport) +#endif +void initmy_module() +{ +    try +    { +       py::Module my_module("my_module"); + +       py::ClassWrapper<Base> base_class(my_module, "Base"); +       base_class.def(py::Constructor<void>()); + +       py::ClassWrapper<Derived> derived_class(my_module, "Derived"); +       derived_class.def(py::Constructor<void>()); + // 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 +    } +} +
+
+ +

+ Then, in Python: +

+
+>>> from my_module import *
+>>> base = Base()
+>>> derived = Derived()
+>>> get_name(base)
+'Base'
+>>> # objects of wrapped class Derived may be passed where Base is expected
+>>> get_name(derived) 
+'Derived'
+>>> # objects of wrapped class Derived can be passed where Derived is 
+>>> # expected but where type information has been lost.
+>>> get_derived_x(base_factory()) 
+-1
+
+
+ +

Inheritance Without Virtual Functions

+ +

+ 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 py::without_downcast as the 2nd parameter + to declare_base: + +

+
+struct Base2 {};
+struct Derived2 { int f(); };
+
+ ... +   py::ClassWrapper<Base> base2_class(my_module, "Base2"); +   base2_class.def(py::Constructor<void>()); + +   py::ClassWrapper<Derived2> derived2_class(my_module, "Derived2"); +   derived2_class.def(py::Constructor<void>()); + derived_class.declare_base(base_class, py::without_downcast); +
+
+ +

This approach will allow Derived2 objects to be passed where + Base2 is expected, but does not attempt to implicitly convert (downcast) + smart-pointers to Base2 into Derived2 pointers, + references, or values. + +

+ Previous: Function Overloading + Next: Special Method Names + Up: Top +

+ © 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. +

+ Updated: Oct 30, 2000 +

+