polymorphism.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. // Copyright David Abrahams 2002.
  2. // Distributed under the Boost Software License, Version 1.0. (See
  3. // accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. #include <boost/python/module.hpp>
  6. #include <boost/python/class.hpp>
  7. #include <boost/python/return_value_policy.hpp>
  8. #include <boost/python/manage_new_object.hpp>
  9. #include <boost/python/reference_existing_object.hpp>
  10. #include <boost/python/call_method.hpp>
  11. #include <boost/python/pure_virtual.hpp>
  12. #include <boost/python/def.hpp>
  13. #include <boost/utility.hpp>
  14. using namespace boost::python;
  15. struct Callback
  16. {
  17. Callback(PyObject* o) : mSelf(o) {}
  18. PyObject* mSelf;
  19. };
  20. struct P
  21. {
  22. virtual ~P(){}
  23. virtual std::string f() = 0;
  24. std::string g() { return "P::g()"; }
  25. };
  26. struct PCallback : P, Callback
  27. {
  28. PCallback (PyObject* self) : Callback(self) {}
  29. std::string f()
  30. {
  31. return call_method<std::string>(mSelf, "f");
  32. }
  33. };
  34. struct Q : virtual P
  35. {
  36. std::string f() { return "Q::f()"; }
  37. };
  38. struct A
  39. {
  40. virtual ~A(){}
  41. virtual std::string f() { return "A::f()"; }
  42. };
  43. struct ACallback : A, Callback
  44. {
  45. ACallback (PyObject* self) : Callback(self) {}
  46. std::string f()
  47. {
  48. return call_method<std::string>(mSelf, "f");
  49. }
  50. std::string default_f()
  51. {
  52. return A::f();
  53. }
  54. };
  55. struct B : A
  56. {
  57. virtual std::string f() { return "B::f()"; }
  58. };
  59. struct C : A
  60. {
  61. virtual std::string f() { return "C::f()"; }
  62. };
  63. struct D : A
  64. {
  65. virtual std::string f() { return "D::f()"; }
  66. std::string g() { return "D::g()"; }
  67. };
  68. struct DCallback : D, Callback
  69. {
  70. DCallback (PyObject* self) : Callback(self) {}
  71. std::string f()
  72. {
  73. return call_method<std::string>(mSelf, "f");
  74. }
  75. std::string default_f()
  76. {
  77. return A::f();
  78. }
  79. };
  80. A& getBCppObj ()
  81. {
  82. static B b;
  83. return b;
  84. }
  85. std::string call_f(A& a) { return a.f(); }
  86. A* factory(unsigned choice)
  87. {
  88. switch (choice % 3)
  89. {
  90. case 0: return new A;
  91. break;
  92. case 1: return new B;
  93. break;
  94. default: return new C;
  95. break;
  96. }
  97. }
  98. C& getCCppObj ()
  99. {
  100. static C c;
  101. return c;
  102. }
  103. A* pass_a(A* x) { return x; }
  104. BOOST_PYTHON_MODULE_INIT(polymorphism_ext)
  105. {
  106. class_<A,boost::noncopyable,ACallback>("A")
  107. .def("f", &A::f, &ACallback::default_f)
  108. ;
  109. def("getBCppObj", getBCppObj, return_value_policy<reference_existing_object>());
  110. class_<C,bases<A>,boost::noncopyable>("C")
  111. .def("f", &C::f)
  112. ;
  113. class_<D,bases<A>,DCallback,boost::noncopyable>("D")
  114. .def("f", &D::f, &DCallback::default_f)
  115. .def("g", &D::g)
  116. ;
  117. def("pass_a", &pass_a, return_internal_reference<>());
  118. def("getCCppObj", getCCppObj, return_value_policy<reference_existing_object>());
  119. def("factory", factory, return_value_policy<manage_new_object>());
  120. def("call_f", call_f);
  121. class_<P,boost::noncopyable,PCallback>("P")
  122. .def("f", pure_virtual(&P::f))
  123. ;
  124. class_<Q, bases<P> >("Q")
  125. .def("g", &P::g) // make sure virtual inheritance doesn't interfere
  126. ;
  127. }
  128. //#include "module_tail.cpp"